@farm.js/core 0.1.51-beta.0 → 0.1.51-beta.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/dist/{agent-mcp-BBMfNpsC.d.ts → agent-mcp.d-CR5Ov83o.d.ts} +1 -1
- package/dist/{agent-mcp-D44ip11f.d.mts → agent-mcp.d-Z5DuwrqW.d.mts} +1 -1
- package/dist/agent-runtime.cjs +3 -3
- package/dist/agent-runtime.d.mts +13 -13
- package/dist/agent-runtime.d.ts +13 -13
- package/dist/agent-runtime.mjs +2 -2
- package/dist/{analyzer-VKUDHNDF.cjs → analyzer-T76CN3S7.cjs} +70 -21
- package/dist/{analyzer-HOUCQR3K.mjs → analyzer-Z6TNEAET.mjs} +70 -21
- package/dist/api/client.d.mts +4 -4
- package/dist/api/client.d.ts +4 -4
- package/dist/api/route-manager.d.mts +19 -19
- package/dist/api/route-manager.d.ts +19 -19
- package/dist/api/runtime.d.mts +15 -15
- package/dist/api/runtime.d.ts +15 -15
- package/dist/{api-client-CvI5oOBE.d.ts → api-client.d-BWcqZciH.d.ts} +3 -3
- package/dist/{api-client-CFdv-Xgh.d.mts → api-client.d-CeA6tNA6.d.mts} +3 -3
- package/dist/api.cjs +3 -3
- package/dist/api.d.mts +21 -21
- package/dist/api.d.ts +21 -21
- package/dist/api.mjs +2 -2
- package/dist/{app-manifest-LzjoNPeq.d.ts → app-manifest.d-CAHkOBFa.d.mts} +1 -1
- package/dist/{app-manifest-BC6mFn5A.d.mts → app-manifest.d-DiWr_Jfx.d.ts} +1 -1
- package/dist/app-markdown.d.mts +14 -14
- package/dist/app-markdown.d.ts +14 -14
- package/dist/{app-aeD4s_mg.d.mts → app.d-BfgJCsTQ.d.mts} +12 -10
- package/dist/{app-CourU3rQ.d.ts → app.d-DmapqkbV.d.ts} +12 -10
- package/dist/{chunk-AMRK3P6W.mjs → chunk-4SSRBCBR.mjs} +233 -84
- package/dist/{chunk-PDJSL7PL.cjs → chunk-5IONBVJY.cjs} +3 -3
- package/dist/{chunk-IOUOGRDX.cjs → chunk-5N7QAGEA.cjs} +25 -6
- package/dist/{chunk-DGOLAZLV.cjs → chunk-65Y5SIBH.cjs} +1 -1
- package/dist/{chunk-ZF3GX4O7.mjs → chunk-6CYQQQGR.mjs} +1 -1
- package/dist/{chunk-QI5AQMEE.mjs → chunk-72NBDVWQ.mjs} +1 -1
- package/dist/{chunk-I2ZA5SXS.mjs → chunk-74Z5KX4A.mjs} +53 -19
- package/dist/chunk-7FVVQEVL.cjs +541 -0
- package/dist/{chunk-OD6WM3I7.mjs → chunk-AV26KHTG.mjs} +1 -1
- package/dist/chunk-C3BOESDW.mjs +541 -0
- package/dist/{chunk-WAPQWAE6.cjs → chunk-CECUDGXQ.cjs} +9 -8
- package/dist/{chunk-IUQLRTTO.mjs → chunk-CO6UYM2D.mjs} +14 -1
- package/dist/{chunk-JF5CNHHF.mjs → chunk-CTM4SPB3.mjs} +123 -8
- package/dist/{chunk-WVX3BUNJ.mjs → chunk-CZ35L6PL.mjs} +8 -1
- package/dist/{chunk-SO3T6T4I.cjs → chunk-DTU4PX7V.cjs} +408 -259
- package/dist/{chunk-YLNBWUVS.mjs → chunk-E6LTONL4.mjs} +1 -1
- package/dist/{chunk-R5P4KFPM.mjs → chunk-E73PGHSR.mjs} +8 -6
- package/dist/{chunk-4GJJ65RB.mjs → chunk-EIMK7D2D.mjs} +24 -5
- package/dist/{chunk-CY7H5KS4.cjs → chunk-EKJYE4Y7.cjs} +2 -2
- package/dist/{chunk-3HA7PP72.mjs → chunk-FM2UEKS2.mjs} +60 -13
- package/dist/{chunk-VIFPE5RG.cjs → chunk-GNJIYJMS.cjs} +81 -34
- package/dist/{chunk-X5BCMLGP.cjs → chunk-GUJTVM36.cjs} +1 -1
- package/dist/{chunk-XWC5NAHV.mjs → chunk-IBSAYAWB.mjs} +2 -2
- package/dist/{chunk-J22JD5YJ.cjs → chunk-J3LBO2O4.cjs} +9 -7
- package/dist/{chunk-J37KTQIA.cjs → chunk-NK2VWS7P.cjs} +52 -3
- package/dist/{chunk-WSY2JD7O.mjs → chunk-NN3MOPSI.mjs} +1 -1
- package/dist/{chunk-O3MMJPC2.cjs → chunk-NPQLMP7M.cjs} +124 -9
- package/dist/{chunk-QK3HBOTG.cjs → chunk-NXBHYO7S.cjs} +5 -5
- package/dist/{chunk-S5ZA2T2W.mjs → chunk-PMKUU273.mjs} +21 -7
- package/dist/{chunk-75WWOZ5C.mjs → chunk-QOSDWGKT.mjs} +1 -1
- package/dist/{chunk-VO6NLTV4.cjs → chunk-QXPSWMUD.cjs} +3 -3
- package/dist/{chunk-Y7TLL65B.cjs → chunk-UQHIWZZ6.cjs} +11 -4
- package/dist/{chunk-PPDHCRTC.mjs → chunk-VS7EHLLW.mjs} +1 -1
- package/dist/{chunk-F42U3R4F.cjs → chunk-WZW6LEHM.cjs} +55 -41
- package/dist/{chunk-USL2ANCB.cjs → chunk-X2AMN2WV.cjs} +2 -2
- package/dist/{chunk-HHFMECFO.mjs → chunk-Y2G5SJFB.mjs} +2 -1
- package/dist/{chunk-Z5MZDFX4.cjs → chunk-YIHRZBD7.cjs} +14 -1
- package/dist/{chunk-DWW3AMJX.cjs → chunk-YU42A5MA.cjs} +282 -248
- package/dist/{chunk-MMEEXMUQ.cjs → chunk-ZOWNWHK6.cjs} +2 -2
- package/dist/{chunk-C5JXCUKR.mjs → chunk-ZQ5BDNKW.mjs} +51 -2
- package/dist/client/lifecycle.d.mts +1 -1
- package/dist/client/lifecycle.d.ts +1 -1
- package/dist/{client-plugins-cqy_dQd0.d.mts → client-plugins.d-Bx3FXpqm.d.mts} +57 -15
- package/dist/{client-plugins-CFBEfVPO.d.ts → client-plugins.d-TiLbS5j4.d.ts} +57 -15
- package/dist/client-plugins.d.mts +13 -13
- package/dist/client-plugins.d.ts +13 -13
- package/dist/client.d.mts +24 -24
- package/dist/client.d.ts +24 -24
- package/dist/{config-CnhyvvmT.d.mts → config.d-iRPI16ku.d.mts} +6 -2
- package/dist/{config-CnhyvvmT.d.ts → config.d-iRPI16ku.d.ts} +6 -2
- package/dist/config.d.mts +13 -13
- package/dist/config.d.ts +13 -13
- package/dist/desktop.d.mts +14 -14
- package/dist/desktop.d.ts +14 -14
- package/dist/{dev-guard-YLO5DE3H.cjs → dev-guard-2UW2KERP.cjs} +2 -2
- package/dist/{dev-guard-4PFQNXQX.mjs → dev-guard-ONNMVQUN.mjs} +1 -1
- package/dist/{devtools-4ZLMD454.cjs → devtools-6XWCZIGO.cjs} +4 -4
- package/dist/{devtools-4MLL3RAL.mjs → devtools-UQLDAOEI.mjs} +3 -3
- package/dist/docs.cjs +8 -6
- package/dist/docs.d.mts +23 -15
- package/dist/docs.d.ts +23 -15
- package/dist/docs.mjs +7 -5
- package/dist/environment/vite.cjs +2 -2
- package/dist/environment/vite.d.mts +1 -1
- package/dist/environment/vite.d.ts +1 -1
- package/dist/environment/vite.mjs +1 -1
- package/dist/{generate-route-types-TF5Wwtvz.d.mts → generate-route-types.d-BL2pq6xC.d.ts} +1 -1
- package/dist/{generate-route-types-DQP0cUzk.d.ts → generate-route-types.d-BoVDU8qX.d.mts} +1 -1
- package/dist/i18n/client.d.mts +2 -2
- package/dist/i18n/client.d.ts +2 -2
- package/dist/i18n/index.d.mts +3 -3
- package/dist/i18n/index.d.ts +3 -3
- package/dist/i18n/server.d.mts +5 -5
- package/dist/i18n/server.d.ts +5 -5
- package/dist/image/server.d.mts +1 -1
- package/dist/image/server.d.ts +1 -1
- package/dist/image/sharp.d.mts +1 -1
- package/dist/image/sharp.d.ts +1 -1
- package/dist/image.d.mts +1 -1
- package/dist/image.d.ts +1 -1
- package/dist/index.cjs +20 -17
- package/dist/{index-D3l4tREW.d.ts → index.d-BNNDpql4.d.ts} +2 -2
- package/dist/{index-DPUAPho_.d.mts → index.d-BqcfqJvt.d.mts} +2 -2
- package/dist/{index-BxjN_UDZ.d.ts → index.d-YxJ2AiDF.d.mts} +2 -2
- package/dist/{index-BYkNbeQV.d.mts → index.d-yueUNipJ.d.ts} +2 -2
- package/dist/index.d.mts +42 -42
- package/dist/index.d.ts +42 -42
- package/dist/index.mjs +19 -16
- package/dist/instrumentation.d.mts +2 -2
- package/dist/instrumentation.d.ts +2 -2
- package/dist/integrations.cjs +3 -3
- package/dist/integrations.d.mts +13 -13
- package/dist/integrations.d.ts +13 -13
- package/dist/integrations.mjs +2 -2
- package/dist/internal/app-markdown-runtime.d.mts +14 -14
- package/dist/internal/app-markdown-runtime.d.ts +14 -14
- package/dist/internal/build-runtime.cjs +16 -15
- package/dist/internal/build-runtime.d.mts +16 -16
- package/dist/internal/build-runtime.d.ts +16 -16
- package/dist/internal/build-runtime.mjs +15 -14
- package/dist/internal/cli-runtime.cjs +7 -7
- package/dist/internal/cli-runtime.mjs +6 -6
- package/dist/internal/client-error-overlay.cjs +4 -4
- package/dist/internal/client-error-overlay.mjs +1 -1
- package/dist/internal/client-runtime.d.mts +21 -21
- package/dist/internal/client-runtime.d.ts +21 -21
- package/dist/internal/compression-runtime.d.mts +13 -13
- package/dist/internal/compression-runtime.d.ts +13 -13
- package/dist/internal/config-runtime.cjs +5 -5
- package/dist/internal/config-runtime.d.mts +29 -92
- package/dist/internal/config-runtime.d.ts +29 -92
- package/dist/internal/config-runtime.mjs +4 -4
- package/dist/internal/form-actions.d.mts +1 -1
- package/dist/internal/form-actions.d.ts +1 -1
- package/dist/internal/infra-analytics-runtime.cjs +5 -5
- package/dist/internal/infra-analytics-runtime.mjs +3 -3
- package/dist/internal/island-value-store.d.mts +1 -1
- package/dist/internal/island-value-store.d.ts +1 -1
- package/dist/internal/islands-runtime.d.mts +1 -1
- package/dist/internal/islands-runtime.d.ts +1 -1
- package/dist/internal/isolated-boundary.d.mts +2 -2
- package/dist/internal/isolated-boundary.d.ts +2 -2
- package/dist/internal/product-telemetry-runtime.cjs +2 -2
- package/dist/internal/product-telemetry-runtime.mjs +1 -1
- package/dist/internal/production-runtime.cjs +11 -3
- package/dist/internal/production-runtime.d.mts +57 -31
- package/dist/internal/production-runtime.d.ts +57 -31
- package/dist/internal/production-runtime.mjs +10 -2
- package/dist/internal/server-tree.d.mts +1 -1
- package/dist/internal/server-tree.d.ts +1 -1
- package/dist/markdown.d.mts +13 -13
- package/dist/markdown.d.ts +13 -13
- package/dist/middleware.cjs +4 -4
- package/dist/middleware.d.mts +15 -15
- package/dist/middleware.d.ts +15 -15
- package/dist/middleware.mjs +3 -3
- package/dist/mobile.d.mts +7 -7
- package/dist/mobile.d.ts +7 -7
- package/dist/{navigation-delegate-BU4xqdnw.d.ts → navigation-delegate.d-BY1e_Xrh.d.ts} +1 -1
- package/dist/{navigation-delegate-DLhbfEN4.d.mts → navigation-delegate.d-HnDXhlyP.d.mts} +1 -1
- package/dist/navigation.d.mts +17 -17
- package/dist/navigation.d.ts +17 -17
- package/dist/observability.d.mts +1 -1
- package/dist/observability.d.ts +1 -1
- package/dist/plugin.cjs +11 -11
- package/dist/plugin.d.mts +17 -17
- package/dist/plugin.d.ts +17 -17
- package/dist/plugin.mjs +10 -10
- package/dist/{production-runtime-DLA4J5WG.d.mts → production-runtime.d-BpJUDzP8.d.mts} +3 -3
- package/dist/{production-runtime-C78A8YgK.d.ts → production-runtime.d-lMjvE9cf.d.ts} +3 -3
- package/dist/{programmatic-routes-client-NpqGBn-i.d.mts → programmatic-routes-client.d-6CGQ3TCk.d.mts} +10 -2
- package/dist/{programmatic-routes-client-CBqkNhBy.d.ts → programmatic-routes-client.d-BlFp5hv4.d.ts} +10 -2
- package/dist/query/client.d.mts +1 -1
- package/dist/query/client.d.ts +1 -1
- package/dist/query/index.d.mts +1 -1
- package/dist/query/index.d.ts +1 -1
- package/dist/query/server.d.mts +1 -1
- package/dist/query/server.d.ts +1 -1
- package/dist/{render-plan-CrqcBbnV.d.ts → render-plan.d-BH9edqKs.d.mts} +2 -2
- package/dist/{render-plan-C9sWvDTv.d.mts → render-plan.d-DhP0mTHF.d.ts} +2 -2
- package/dist/renderer-client.d.mts +19 -19
- package/dist/renderer-client.d.ts +19 -19
- package/dist/{request-BizeuqD7.d.ts → request.d-BVZrsR1v.d.ts} +1 -1
- package/dist/{request-WwB1-Uim.d.mts → request.d-DJFRdKi8.d.mts} +1 -1
- package/dist/request.d.mts +14 -14
- package/dist/request.d.ts +14 -14
- package/dist/{resolver-CJ-D9nP-.d.ts → resolver.d-BHyZgpa7.d.ts} +1 -1
- package/dist/{resolver-TDyZKgKI.d.mts → resolver.d-JnZKKsc5.d.mts} +1 -1
- package/dist/response.d-BolW0Vx_.d.mts +10 -0
- package/dist/response.d-BolW0Vx_.d.ts +10 -0
- package/dist/{route-rendering-BGhJN64l.d.ts → route-rendering.d-B00JtK_-.d.ts} +1 -1
- package/dist/{route-rendering-S6NFjnx4.d.mts → route-rendering.d-Bpmw7PED.d.mts} +1 -1
- package/dist/{route-2_yXC6gv.d.mts → route.d-BaVH3V0w.d.mts} +1 -1
- package/dist/{route-DFhZj6jN.d.ts → route.d-DBTEqifW.d.ts} +1 -1
- package/dist/{router-BUD_j2EL.d.ts → router.d-Bd1x9XxQ.d.ts} +1 -1
- package/dist/{router-BIheIy9G.d.mts → router.d-e0jQ3jQ-.d.mts} +1 -1
- package/dist/{routes-kEUsXHx3.d.mts → routes.d-Cmv8TgVq.d.mts} +91 -4
- package/dist/{routes-8PT9cl60.d.ts → routes.d-D96Dq9lz.d.ts} +91 -4
- package/dist/routes.d.mts +13 -13
- package/dist/routes.d.ts +13 -13
- package/dist/{rsc-pipeline-JRGUZBYM.cjs → rsc-pipeline-DX4OC5FN.cjs} +6 -6
- package/dist/{rsc-pipeline-OLAVIKI3.mjs → rsc-pipeline-ZQ4CTVEG.mjs} +5 -5
- package/dist/{runtime-OGCHDACZ.mjs → runtime-NPDRDV6R.mjs} +66 -17
- package/dist/{runtime-G23RSLEK.cjs → runtime-NQ3EDSA7.cjs} +75 -26
- package/dist/{runtime-CihDZ2Rn.d.mts → runtime.d-3iJAKptR.d.mts} +2 -2
- package/dist/{runtime-C4CmlOOh.d.ts → runtime.d-BtL3PCL3.d.ts} +2 -2
- package/dist/{runtime-CWP-21hP.d.ts → runtime.d-CgB3IJDq.d.mts} +4 -4
- package/dist/{runtime-CgJwe6H_.d.mts → runtime.d-D-td-RR3.d.ts} +4 -4
- package/dist/server-action-security.d.mts +1 -1
- package/dist/server-action-security.d.ts +1 -1
- package/dist/server-fn-client.d.mts +5 -5
- package/dist/server-fn-client.d.ts +5 -5
- package/dist/server-fn.d.mts +3 -3
- package/dist/server-fn.d.ts +3 -3
- package/dist/server-plugins.d.mts +14 -14
- package/dist/server-plugins.d.ts +14 -14
- package/dist/server-query-client.d.mts +5 -5
- package/dist/server-query-client.d.ts +5 -5
- package/dist/server-query.d.mts +2 -2
- package/dist/server-query.d.ts +2 -2
- package/dist/server.cjs +31 -31
- package/dist/server.d.mts +28 -29
- package/dist/server.d.ts +28 -29
- package/dist/server.mjs +13 -13
- package/dist/session-AAU7RNRO.cjs +23 -0
- package/dist/session-IGEDQ5PY.mjs +23 -0
- package/dist/{spa-router-Kytv4jSB.d.ts → spa-router.d-BWDhS0FK.d.mts} +5 -5
- package/dist/{spa-router-CVOL0Vrq.d.mts → spa-router.d-CO01mVOM.d.ts} +5 -5
- package/dist/storage.d.mts +2 -2
- package/dist/storage.d.ts +2 -2
- package/dist/testing.d.mts +14 -14
- package/dist/testing.d.ts +14 -14
- package/dist/theme/client.d.mts +1 -1
- package/dist/theme/client.d.ts +1 -1
- package/dist/theme/index.d.mts +2 -2
- package/dist/theme/index.d.ts +2 -2
- package/dist/theme/runtime.d.mts +1 -1
- package/dist/theme/runtime.d.ts +1 -1
- package/dist/theme/server.d.mts +1 -1
- package/dist/theme/server.d.ts +1 -1
- package/dist/{utils-DbyXlzaj.d.ts → utils.d-B77__yh8.d.ts} +1 -1
- package/dist/{utils-Dsa1HZ7X.d.mts → utils.d-DRDazhCA.d.mts} +1 -1
- package/dist/version.cjs +2 -2
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +11 -11
- package/dist/vite.d.mts +20 -19
- package/dist/vite.d.ts +20 -19
- package/dist/vite.mjs +10 -10
- package/dist/workflows.d.mts +1 -1
- package/dist/workflows.d.ts +1 -1
- package/package.json +5 -5
- /package/dist/{base-path-BOUV5ozD.d.mts → base-path.d-BOUV5ozD.d.mts} +0 -0
- /package/dist/{base-path-BOUV5ozD.d.ts → base-path.d-BOUV5ozD.d.ts} +0 -0
- /package/dist/{chunk-recovery-lnQFzcQP.d.mts → chunk-recovery.d-lnQFzcQP.d.mts} +0 -0
- /package/dist/{chunk-recovery-lnQFzcQP.d.ts → chunk-recovery.d-lnQFzcQP.d.ts} +0 -0
- /package/dist/{client-cache-Deoqq-nM.d.ts → client-cache.d-Deoqq-nM.d.ts} +0 -0
- /package/dist/{client-cache-di_Nasxa.d.mts → client-cache.d-di_Nasxa.d.mts} +0 -0
- /package/dist/{endpoint-BgHn0lhl.d.ts → endpoint.d-BgHn0lhl.d.ts} +0 -0
- /package/dist/{endpoint-BkMSCRf6.d.mts → endpoint.d-BkMSCRf6.d.mts} +0 -0
- /package/dist/{image-config-CeDgNyX4.d.mts → image-config.d-CeDgNyX4.d.mts} +0 -0
- /package/dist/{image-config-CeDgNyX4.d.ts → image-config.d-CeDgNyX4.d.ts} +0 -0
- /package/dist/{instrumentation-runtime-CX9Zh-16.d.mts → instrumentation-runtime.d-CX9Zh-16.d.mts} +0 -0
- /package/dist/{instrumentation-runtime-CX9Zh-16.d.ts → instrumentation-runtime.d-CX9Zh-16.d.ts} +0 -0
- /package/dist/{island-value-protocol-BRayRghM.d.mts → island-value-protocol.d-BRayRghM.d.mts} +0 -0
- /package/dist/{island-value-protocol-BRayRghM.d.ts → island-value-protocol.d-BRayRghM.d.ts} +0 -0
- /package/dist/{island-CfGru1MO.d.mts → island.d-CfGru1MO.d.mts} +0 -0
- /package/dist/{island-CfGru1MO.d.ts → island.d-CfGru1MO.d.ts} +0 -0
- /package/dist/{layers-CcS42OGR.d.mts → layers.d-CcS42OGR.d.mts} +0 -0
- /package/dist/{layers-CcS42OGR.d.ts → layers.d-CcS42OGR.d.ts} +0 -0
- /package/dist/{lifecycle-C2aLBOwu.d.mts → lifecycle.d-C2aLBOwu.d.mts} +0 -0
- /package/dist/{lifecycle-C2aLBOwu.d.ts → lifecycle.d-C2aLBOwu.d.ts} +0 -0
- /package/dist/{observability-B2363jB6.d.mts → observability.d-B2363jB6.d.mts} +0 -0
- /package/dist/{observability-B2363jB6.d.ts → observability.d-B2363jB6.d.ts} +0 -0
- /package/dist/{params-BALtrRim.d.ts → params.d-BALtrRim.d.ts} +0 -0
- /package/dist/{params-ry-lxqmy.d.mts → params.d-ry-lxqmy.d.mts} +0 -0
- /package/dist/{production-vite-BQFAlG7n.d.mts → production-vite.d-BQFAlG7n.d.mts} +0 -0
- /package/dist/{production-vite-BQFAlG7n.d.ts → production-vite.d-BQFAlG7n.d.ts} +0 -0
- /package/dist/{route-pattern-CVsVbq5n.d.mts → route-pattern.d-CVsVbq5n.d.mts} +0 -0
- /package/dist/{route-pattern-CVsVbq5n.d.ts → route-pattern.d-CVsVbq5n.d.ts} +0 -0
- /package/dist/{server-client-bridge-DKWDl5NB.d.mts → server-client-bridge.d-DKWDl5NB.d.mts} +0 -0
- /package/dist/{server-client-bridge-DKWDl5NB.d.ts → server-client-bridge.d-DKWDl5NB.d.ts} +0 -0
- /package/dist/{server-fn-error-DrcH9cc1.d.mts → server-fn-error.d-DrcH9cc1.d.mts} +0 -0
- /package/dist/{server-fn-error-DrcH9cc1.d.ts → server-fn-error.d-DrcH9cc1.d.ts} +0 -0
- /package/dist/{server-query-runtime-DXRNhX_3.d.ts → server-query-runtime.d-DXRNhX_3.d.ts} +0 -0
- /package/dist/{server-query-runtime-aP52iuL5.d.mts → server-query-runtime.d-aP52iuL5.d.mts} +0 -0
- /package/dist/{types-BnIqOn9w.d.mts → types.d-BnIqOn9w.d.mts} +0 -0
- /package/dist/{types-BnIqOn9w.d.ts → types.d-BnIqOn9w.d.ts} +0 -0
- /package/dist/{types-C41ePjvP.d.mts → types.d-C41ePjvP.d.mts} +0 -0
- /package/dist/{types-C41ePjvP.d.ts → types.d-C41ePjvP.d.ts} +0 -0
- /package/dist/{types-DQnyD3VD.d.mts → types.d-DQnyD3VD.d.mts} +0 -0
- /package/dist/{types-DQnyD3VD.d.ts → types.d-DQnyD3VD.d.ts} +0 -0
- /package/dist/{workflows-CRMzQZ3k.d.mts → workflows.d-CRMzQZ3k.d.mts} +0 -0
- /package/dist/{workflows-CRMzQZ3k.d.ts → workflows.d-CRMzQZ3k.d.ts} +0 -0
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
var _chunkJMYXO572cjs = require('./chunk-JMYXO572.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
var _chunkSHIWRBFIcjs = require('./chunk-SHIWRBFI.cjs');
|
|
7
|
+
|
|
8
|
+
// src/mobile/session.ts
|
|
9
|
+
var FARM_MOBILE_SESSION_PLUGIN = "farm:mobile-session";
|
|
10
|
+
var FARM_MOBILE_SESSION_PATH = "/__farm/mobile/session";
|
|
11
|
+
var FARM_MOBILE_APP_HEADER = "x-farm-mobile";
|
|
12
|
+
var FARM_MOBILE_NONCE_HEADER = "x-farm-mobile-nonce";
|
|
13
|
+
var FARM_MOBILE_DEVICE_COOKIE = "farm_mobile";
|
|
14
|
+
var ACCESS_PREFIX = "fma1";
|
|
15
|
+
var REFRESH_PREFIX = "fmr1";
|
|
16
|
+
var STORAGE_NAMESPACE = "farm-mobile";
|
|
17
|
+
var STATE_KEY = "farm:mobile-session";
|
|
18
|
+
var USED_REFRESH_LIMIT = 8;
|
|
19
|
+
var BROWSER_HEADERS = [
|
|
20
|
+
"origin",
|
|
21
|
+
"sec-fetch-site",
|
|
22
|
+
"sec-fetch-mode",
|
|
23
|
+
"sec-fetch-dest",
|
|
24
|
+
"sec-fetch-user"
|
|
25
|
+
];
|
|
26
|
+
var APP_ID = /^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$/;
|
|
27
|
+
var BASE64URL = /^[A-Za-z0-9_-]+$/;
|
|
28
|
+
var encoder = new TextEncoder();
|
|
29
|
+
var decoder = new TextDecoder();
|
|
30
|
+
function toBase64Url(bytes) {
|
|
31
|
+
let binary = "";
|
|
32
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
33
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
34
|
+
}
|
|
35
|
+
function fromBase64Url(value) {
|
|
36
|
+
const base64 = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
37
|
+
const binary = atob(base64 + "=".repeat((4 - base64.length % 4) % 4));
|
|
38
|
+
const bytes = new Uint8Array(binary.length);
|
|
39
|
+
for (let index = 0; index < binary.length; index++) bytes[index] = binary.charCodeAt(index);
|
|
40
|
+
return bytes;
|
|
41
|
+
}
|
|
42
|
+
function randomToken(bytes) {
|
|
43
|
+
return toBase64Url(globalThis.crypto.getRandomValues(new Uint8Array(bytes)));
|
|
44
|
+
}
|
|
45
|
+
async function sha256(value) {
|
|
46
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", encoder.encode(value));
|
|
47
|
+
return toBase64Url(new Uint8Array(digest));
|
|
48
|
+
}
|
|
49
|
+
async function aesKey(key) {
|
|
50
|
+
return globalThis.crypto.subtle.importKey("raw", fromBase64Url(key), "AES-GCM", false, [
|
|
51
|
+
"encrypt",
|
|
52
|
+
"decrypt"
|
|
53
|
+
]);
|
|
54
|
+
}
|
|
55
|
+
async function sealJar(jar, key, deviceId) {
|
|
56
|
+
const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));
|
|
57
|
+
const data = await globalThis.crypto.subtle.encrypt(
|
|
58
|
+
{ name: "AES-GCM", iv, additionalData: encoder.encode(deviceId) },
|
|
59
|
+
await aesKey(key),
|
|
60
|
+
encoder.encode(JSON.stringify(jar))
|
|
61
|
+
);
|
|
62
|
+
return { iv: toBase64Url(iv), data: toBase64Url(new Uint8Array(data)) };
|
|
63
|
+
}
|
|
64
|
+
async function openJar(sealed, key, deviceId) {
|
|
65
|
+
try {
|
|
66
|
+
const data = await globalThis.crypto.subtle.decrypt(
|
|
67
|
+
{ name: "AES-GCM", iv: fromBase64Url(sealed.iv), additionalData: encoder.encode(deviceId) },
|
|
68
|
+
await aesKey(key),
|
|
69
|
+
fromBase64Url(sealed.data)
|
|
70
|
+
);
|
|
71
|
+
const jar = JSON.parse(decoder.decode(data));
|
|
72
|
+
if (!jar || typeof jar !== "object" || Array.isArray(jar)) return null;
|
|
73
|
+
return Object.fromEntries(
|
|
74
|
+
Object.entries(jar).filter(
|
|
75
|
+
(entry) => typeof entry[1] === "string"
|
|
76
|
+
)
|
|
77
|
+
);
|
|
78
|
+
} catch (e) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function formatToken(prefix, token) {
|
|
83
|
+
return `${prefix}.${token.deviceId}.${token.secret}.${token.key}`;
|
|
84
|
+
}
|
|
85
|
+
function parseFarmMobileToken(value, kind) {
|
|
86
|
+
if (typeof value !== "string" || value.length > 256) return null;
|
|
87
|
+
const parts = value.split(".");
|
|
88
|
+
if (parts.length !== 4 || parts[0] !== (kind === "access" ? ACCESS_PREFIX : REFRESH_PREFIX)) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const [, deviceId, secret, key] = parts;
|
|
92
|
+
if (deviceId.length !== 22 || secret.length !== 43 || key.length !== 43) return null;
|
|
93
|
+
if (!BASE64URL.test(deviceId) || !BASE64URL.test(secret) || !BASE64URL.test(key)) return null;
|
|
94
|
+
return { deviceId, secret, key };
|
|
95
|
+
}
|
|
96
|
+
function readCookies(header) {
|
|
97
|
+
const cookies = {};
|
|
98
|
+
for (const part of (_nullishCoalesce(header, () => ( ""))).split(";")) {
|
|
99
|
+
const separator = part.indexOf("=");
|
|
100
|
+
if (separator <= 0) continue;
|
|
101
|
+
const name = part.slice(0, separator).trim();
|
|
102
|
+
if (!name || name === "__proto__" || name in cookies) continue;
|
|
103
|
+
cookies[name] = part.slice(separator + 1).trim();
|
|
104
|
+
}
|
|
105
|
+
return cookies;
|
|
106
|
+
}
|
|
107
|
+
function cookieHeader(jar) {
|
|
108
|
+
return Object.entries(jar).map(([name, value]) => `${name}=${value}`).join("; ");
|
|
109
|
+
}
|
|
110
|
+
function readSetCookies(headers, now) {
|
|
111
|
+
const changes = [];
|
|
112
|
+
for (const line of headers.getSetCookie()) {
|
|
113
|
+
const [pair = "", ...attributes] = line.split(";");
|
|
114
|
+
const separator = pair.indexOf("=");
|
|
115
|
+
if (separator <= 0) continue;
|
|
116
|
+
const name = pair.slice(0, separator).trim();
|
|
117
|
+
if (!name || name === "__proto__") continue;
|
|
118
|
+
let expired = false;
|
|
119
|
+
for (const attribute of attributes) {
|
|
120
|
+
const [rawKey = "", ...rest] = attribute.split("=");
|
|
121
|
+
const key = rawKey.trim().toLowerCase();
|
|
122
|
+
const value = rest.join("=").trim();
|
|
123
|
+
if (key === "max-age" && /^-?\d+$/.test(value)) expired = Number(value) <= 0;
|
|
124
|
+
if (key === "expires" && !attributes.some((item) => /^\s*max-age=/i.test(item))) {
|
|
125
|
+
const time = Date.parse(value);
|
|
126
|
+
if (!Number.isNaN(time) && time <= now) expired = true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
changes.push([name, expired ? null : pair.slice(separator + 1).trim()]);
|
|
130
|
+
}
|
|
131
|
+
return changes;
|
|
132
|
+
}
|
|
133
|
+
function applySetCookies(jar, changes) {
|
|
134
|
+
const next = { ...jar };
|
|
135
|
+
for (const [name, value] of changes) {
|
|
136
|
+
if (name === FARM_MOBILE_DEVICE_COOKIE) continue;
|
|
137
|
+
if (value === null) delete next[name];
|
|
138
|
+
else next[name] = value;
|
|
139
|
+
}
|
|
140
|
+
return next;
|
|
141
|
+
}
|
|
142
|
+
function json(body, status = 200, headers) {
|
|
143
|
+
const response = Response.json(body, { status, headers });
|
|
144
|
+
response.headers.set("cache-control", "no-store");
|
|
145
|
+
return response;
|
|
146
|
+
}
|
|
147
|
+
function failure(status, error, message) {
|
|
148
|
+
const response = json({ error, message }, status);
|
|
149
|
+
if (status === 401) {
|
|
150
|
+
response.headers.set("www-authenticate", `Bearer error="invalid_token"`);
|
|
151
|
+
}
|
|
152
|
+
return response;
|
|
153
|
+
}
|
|
154
|
+
function isFarmMobileNativeRequest(request) {
|
|
155
|
+
return !BROWSER_HEADERS.some((name) => request.headers.has(name));
|
|
156
|
+
}
|
|
157
|
+
function readAppId(request) {
|
|
158
|
+
const value = _optionalChain([request, 'access', _ => _.headers, 'access', _2 => _2.get, 'call', _3 => _3(FARM_MOBILE_APP_HEADER), 'optionalAccess', _4 => _4.trim, 'call', _5 => _5()]);
|
|
159
|
+
return value && value.length <= 255 && APP_ID.test(value) ? value : null;
|
|
160
|
+
}
|
|
161
|
+
function bearer(request) {
|
|
162
|
+
const header = request.headers.get("authorization");
|
|
163
|
+
if (!header) return null;
|
|
164
|
+
const match = /^bearer\s+(\S+)$/i.exec(header.trim());
|
|
165
|
+
return match ? match[1] : null;
|
|
166
|
+
}
|
|
167
|
+
var SessionReadError = class extends Error {
|
|
168
|
+
constructor(message, reason) {
|
|
169
|
+
super(message);
|
|
170
|
+
this.reason = reason;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
function createFarmMobileSessionPlugin(options) {
|
|
174
|
+
const basePath = options.basePath && options.basePath !== "/" ? options.basePath : "";
|
|
175
|
+
const accessTtl = (_nullishCoalesce(options.accessTokenTtl, () => ( 15 * 60))) * 1e3;
|
|
176
|
+
const refreshTtl = (_nullishCoalesce(options.refreshTokenTtl, () => ( 30 * 24 * 60 * 60))) * 1e3;
|
|
177
|
+
const nonceTtl = (_nullishCoalesce(options.nonceTtl, () => ( 60))) * 1e3;
|
|
178
|
+
const now = _nullishCoalesce(options.now, () => ( Date.now));
|
|
179
|
+
const store = () => _nullishCoalesce(_optionalChain([options, 'access', _6 => _6.storage, 'optionalCall', _7 => _7()]), () => ( _chunkJMYXO572cjs.getStorage.call(void 0, STORAGE_NAMESPACE)));
|
|
180
|
+
let warnedNoReader = false;
|
|
181
|
+
function sessionReader() {
|
|
182
|
+
for (const integration of Object.values(_nullishCoalesce(options.integrations(), () => ( {})))) {
|
|
183
|
+
const session = _optionalChain([integration, 'optionalAccess', _8 => _8.session]);
|
|
184
|
+
if (typeof session === "function") {
|
|
185
|
+
return (request) => session.call(integration, request);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
async function readSession(reader, url, cookies) {
|
|
191
|
+
const header = cookieHeader(cookies);
|
|
192
|
+
if (!header) return null;
|
|
193
|
+
let session;
|
|
194
|
+
try {
|
|
195
|
+
session = await reader(new Request(url, { headers: { cookie: header } }));
|
|
196
|
+
} catch (error) {
|
|
197
|
+
throw new SessionReadError("The auth integration's session() failed", error);
|
|
198
|
+
}
|
|
199
|
+
const id = _optionalChain([session, 'optionalAccess', _9 => _9.id]);
|
|
200
|
+
return typeof id === "string" && id ? session : null;
|
|
201
|
+
}
|
|
202
|
+
function noReader() {
|
|
203
|
+
if (!warnedNoReader) {
|
|
204
|
+
warnedNoReader = true;
|
|
205
|
+
console.warn(
|
|
206
|
+
"[Farm] Mobile session tokens need an auth integration that reads sessions (`session()`): @farm.js/auth (`auth: true`) or @farm.js/better-auth. No configured integration has one, so native screens stay signed out."
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
return failure(
|
|
210
|
+
501,
|
|
211
|
+
"mobile_session_unavailable",
|
|
212
|
+
"No auth integration in this app reads sessions for mobile tokens."
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
function markerCookie(request, value, maxAge) {
|
|
216
|
+
const secure = new URL(request.url).protocol === "https:" ? "; Secure" : "";
|
|
217
|
+
return `${FARM_MOBILE_DEVICE_COOKIE}=${value}; Path=${basePath || "/"}; Max-Age=${maxAge}; HttpOnly; SameSite=Lax${secure}`;
|
|
218
|
+
}
|
|
219
|
+
async function loadDevice(deviceId) {
|
|
220
|
+
const record = await store().getItem(`device:${deviceId}`);
|
|
221
|
+
return record && record.v === 1 ? record : null;
|
|
222
|
+
}
|
|
223
|
+
async function saveDevice(deviceId, record) {
|
|
224
|
+
await store().setItem(`device:${deviceId}`, record);
|
|
225
|
+
}
|
|
226
|
+
async function revokeDevice(deviceId) {
|
|
227
|
+
await store().removeItem(`device:${deviceId}`);
|
|
228
|
+
}
|
|
229
|
+
async function challengeKey(sessionId, appId) {
|
|
230
|
+
return `challenge:${await sha256(`${sessionId}
|
|
231
|
+
${appId}`)}`;
|
|
232
|
+
}
|
|
233
|
+
async function issueTokens(deviceId, key, base, jar) {
|
|
234
|
+
const access = { deviceId, secret: randomToken(32), key };
|
|
235
|
+
const refresh2 = { deviceId, secret: randomToken(32), key };
|
|
236
|
+
const issuedAt = now();
|
|
237
|
+
const record = {
|
|
238
|
+
...base,
|
|
239
|
+
accessHash: await sha256(access.secret),
|
|
240
|
+
accessExpiresAt: issuedAt + accessTtl,
|
|
241
|
+
refreshHash: await sha256(refresh2.secret),
|
|
242
|
+
refreshExpiresAt: issuedAt + refreshTtl,
|
|
243
|
+
jar: await sealJar(jar, key, deviceId)
|
|
244
|
+
};
|
|
245
|
+
await saveDevice(deviceId, record);
|
|
246
|
+
return {
|
|
247
|
+
record,
|
|
248
|
+
body: {
|
|
249
|
+
tokenType: "Bearer",
|
|
250
|
+
accessToken: formatToken(ACCESS_PREFIX, access),
|
|
251
|
+
refreshToken: formatToken(REFRESH_PREFIX, refresh2),
|
|
252
|
+
expiresIn: Math.floor(accessTtl / 1e3),
|
|
253
|
+
refreshExpiresIn: Math.floor(refreshTtl / 1e3)
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
function guardEndpoint(request) {
|
|
258
|
+
if (request.method !== "POST") {
|
|
259
|
+
return new Response("Method Not Allowed", {
|
|
260
|
+
status: 405,
|
|
261
|
+
headers: { allow: "POST", "cache-control": "no-store" }
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
if (!isFarmMobileNativeRequest(request)) {
|
|
265
|
+
return failure(403, "not_native", "Mobile session endpoints answer the app's shell only.");
|
|
266
|
+
}
|
|
267
|
+
const appId = readAppId(request);
|
|
268
|
+
if (!appId) {
|
|
269
|
+
return failure(400, "invalid_app", `Send the app's mobile.id in ${FARM_MOBILE_APP_HEADER}.`);
|
|
270
|
+
}
|
|
271
|
+
return { appId };
|
|
272
|
+
}
|
|
273
|
+
async function challenge(request) {
|
|
274
|
+
const guard = guardEndpoint(request);
|
|
275
|
+
if (guard instanceof Response) return guard;
|
|
276
|
+
const reader = sessionReader();
|
|
277
|
+
if (!reader) return noReader();
|
|
278
|
+
const cookies = readCookies(request.headers.get("cookie"));
|
|
279
|
+
delete cookies[FARM_MOBILE_DEVICE_COOKIE];
|
|
280
|
+
const session = await readSession(reader, request.url, cookies);
|
|
281
|
+
if (!session) return failure(401, "signed_out", "Sign in on a web screen first.");
|
|
282
|
+
const nonce = randomToken(32);
|
|
283
|
+
await store().setItem(await challengeKey(session.id, guard.appId), {
|
|
284
|
+
hash: await sha256(nonce),
|
|
285
|
+
expiresAt: now() + nonceTtl
|
|
286
|
+
});
|
|
287
|
+
return json({ nonce, expiresIn: Math.floor(nonceTtl / 1e3) });
|
|
288
|
+
}
|
|
289
|
+
async function issue(request) {
|
|
290
|
+
const guard = guardEndpoint(request);
|
|
291
|
+
if (guard instanceof Response) return guard;
|
|
292
|
+
const reader = sessionReader();
|
|
293
|
+
if (!reader) return noReader();
|
|
294
|
+
const nonce = _nullishCoalesce(_optionalChain([request, 'access', _10 => _10.headers, 'access', _11 => _11.get, 'call', _12 => _12(FARM_MOBILE_NONCE_HEADER), 'optionalAccess', _13 => _13.trim, 'call', _14 => _14()]), () => ( ""));
|
|
295
|
+
const cookies = readCookies(request.headers.get("cookie"));
|
|
296
|
+
delete cookies[FARM_MOBILE_DEVICE_COOKIE];
|
|
297
|
+
const session = await readSession(reader, request.url, cookies);
|
|
298
|
+
if (!session) return failure(401, "signed_out", "Sign in on a web screen first.");
|
|
299
|
+
const key = await challengeKey(session.id, guard.appId);
|
|
300
|
+
const pending = await store().getItem(key);
|
|
301
|
+
if (pending) await store().removeItem(key);
|
|
302
|
+
if (!pending || pending.expiresAt <= now() || !nonce || !_chunkSHIWRBFIcjs.farmSecretsMatch.call(void 0, await sha256(nonce), pending.hash)) {
|
|
303
|
+
return failure(401, "invalid_nonce", "Request a new challenge and try again.");
|
|
304
|
+
}
|
|
305
|
+
const deviceId = randomToken(16);
|
|
306
|
+
const { body: tokens } = await issueTokens(
|
|
307
|
+
deviceId,
|
|
308
|
+
randomToken(32),
|
|
309
|
+
{
|
|
310
|
+
v: 1,
|
|
311
|
+
appId: guard.appId,
|
|
312
|
+
sessionHash: await sha256(session.id),
|
|
313
|
+
createdAt: now(),
|
|
314
|
+
usedRefreshHashes: []
|
|
315
|
+
},
|
|
316
|
+
cookies
|
|
317
|
+
);
|
|
318
|
+
const response = json(tokens);
|
|
319
|
+
response.headers.append(
|
|
320
|
+
"set-cookie",
|
|
321
|
+
markerCookie(request, deviceId, Math.floor(refreshTtl / 1e3))
|
|
322
|
+
);
|
|
323
|
+
return response;
|
|
324
|
+
}
|
|
325
|
+
async function refresh(request) {
|
|
326
|
+
const guard = guardEndpoint(request);
|
|
327
|
+
if (guard instanceof Response) return guard;
|
|
328
|
+
const reader = sessionReader();
|
|
329
|
+
if (!reader) return noReader();
|
|
330
|
+
const token = parseFarmMobileToken(bearer(request), "refresh");
|
|
331
|
+
if (!token) return failure(401, "invalid_token", "Unknown refresh token.");
|
|
332
|
+
const record = await loadDevice(token.deviceId);
|
|
333
|
+
if (!record) return failure(401, "invalid_token", "Unknown refresh token.");
|
|
334
|
+
if (record.appId !== guard.appId) {
|
|
335
|
+
return failure(401, "invalid_token", "The token belongs to another app.");
|
|
336
|
+
}
|
|
337
|
+
const hash = await sha256(token.secret);
|
|
338
|
+
if (!_chunkSHIWRBFIcjs.farmSecretsMatch.call(void 0, hash, record.refreshHash)) {
|
|
339
|
+
if (record.usedRefreshHashes.some((used) => _chunkSHIWRBFIcjs.farmSecretsMatch.call(void 0, hash, used))) {
|
|
340
|
+
await revokeDevice(token.deviceId);
|
|
341
|
+
return failure(401, "refresh_reused", "The refresh token was already used.");
|
|
342
|
+
}
|
|
343
|
+
return failure(401, "invalid_token", "Unknown refresh token.");
|
|
344
|
+
}
|
|
345
|
+
if (record.refreshExpiresAt <= now()) {
|
|
346
|
+
await revokeDevice(token.deviceId);
|
|
347
|
+
return failure(401, "invalid_token", "The refresh token expired.");
|
|
348
|
+
}
|
|
349
|
+
const jar = await openJar(record.jar, token.key, token.deviceId);
|
|
350
|
+
if (!jar) return failure(401, "invalid_token", "Unknown refresh token.");
|
|
351
|
+
let session;
|
|
352
|
+
try {
|
|
353
|
+
session = await readSession(reader, request.url, jar);
|
|
354
|
+
} catch (error) {
|
|
355
|
+
console.error("[Farm] Mobile session refresh could not read the session:", error);
|
|
356
|
+
return failure(503, "session_unavailable", "Try again later.");
|
|
357
|
+
}
|
|
358
|
+
if (!session || await sha256(session.id) !== record.sessionHash) {
|
|
359
|
+
await revokeDevice(token.deviceId);
|
|
360
|
+
return failure(401, "signed_out", "The web session behind this device ended.");
|
|
361
|
+
}
|
|
362
|
+
const { body: tokens } = await issueTokens(
|
|
363
|
+
token.deviceId,
|
|
364
|
+
randomToken(32),
|
|
365
|
+
{
|
|
366
|
+
v: 1,
|
|
367
|
+
appId: record.appId,
|
|
368
|
+
sessionHash: record.sessionHash,
|
|
369
|
+
createdAt: record.createdAt,
|
|
370
|
+
usedRefreshHashes: [record.refreshHash, ...record.usedRefreshHashes].slice(
|
|
371
|
+
0,
|
|
372
|
+
USED_REFRESH_LIMIT
|
|
373
|
+
)
|
|
374
|
+
},
|
|
375
|
+
jar
|
|
376
|
+
);
|
|
377
|
+
const response = json(tokens);
|
|
378
|
+
response.headers.append(
|
|
379
|
+
"set-cookie",
|
|
380
|
+
markerCookie(request, token.deviceId, Math.floor(refreshTtl / 1e3))
|
|
381
|
+
);
|
|
382
|
+
return response;
|
|
383
|
+
}
|
|
384
|
+
async function revoke(request) {
|
|
385
|
+
const guard = guardEndpoint(request);
|
|
386
|
+
if (guard instanceof Response) return guard;
|
|
387
|
+
const access = parseFarmMobileToken(bearer(request), "access");
|
|
388
|
+
const token = _nullishCoalesce(access, () => ( parseFarmMobileToken(bearer(request), "refresh")));
|
|
389
|
+
if (token) {
|
|
390
|
+
const record = await loadDevice(token.deviceId);
|
|
391
|
+
const hash = await sha256(token.secret);
|
|
392
|
+
if (record && record.appId === guard.appId && _chunkSHIWRBFIcjs.farmSecretsMatch.call(void 0, hash, access ? record.accessHash : record.refreshHash)) {
|
|
393
|
+
await revokeDevice(token.deviceId);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
const response = new Response(null, { status: 204, headers: { "cache-control": "no-store" } });
|
|
397
|
+
response.headers.append("set-cookie", markerCookie(request, "", 0));
|
|
398
|
+
return response;
|
|
399
|
+
}
|
|
400
|
+
async function before(event) {
|
|
401
|
+
const { request } = event;
|
|
402
|
+
const value = bearer(request);
|
|
403
|
+
if (!_optionalChain([value, 'optionalAccess', _15 => _15.startsWith, 'call', _16 => _16(`${ACCESS_PREFIX}.`)])) return void 0;
|
|
404
|
+
if (!isFarmMobileNativeRequest(request)) return void 0;
|
|
405
|
+
const token = parseFarmMobileToken(value, "access");
|
|
406
|
+
if (!token) return failure(401, "invalid_token", "Unknown access token.");
|
|
407
|
+
const appId = readAppId(request);
|
|
408
|
+
const record = await loadDevice(token.deviceId);
|
|
409
|
+
const hash = await sha256(token.secret);
|
|
410
|
+
if (!record || !_chunkSHIWRBFIcjs.farmSecretsMatch.call(void 0, hash, record.accessHash)) {
|
|
411
|
+
return failure(401, "invalid_token", "Unknown access token.");
|
|
412
|
+
}
|
|
413
|
+
if (!appId || appId !== record.appId) {
|
|
414
|
+
return failure(401, "invalid_token", "The token belongs to another app.");
|
|
415
|
+
}
|
|
416
|
+
if (record.accessExpiresAt <= now()) {
|
|
417
|
+
return failure(401, "invalid_token", "The access token expired.");
|
|
418
|
+
}
|
|
419
|
+
const jar = await openJar(record.jar, token.key, token.deviceId);
|
|
420
|
+
if (!jar) return failure(401, "invalid_token", "Unknown access token.");
|
|
421
|
+
const headers = new Headers(request.headers);
|
|
422
|
+
headers.delete("authorization");
|
|
423
|
+
headers.delete("cookie");
|
|
424
|
+
const cookies = cookieHeader(jar);
|
|
425
|
+
if (cookies) headers.set("cookie", cookies);
|
|
426
|
+
headers.set("origin", new URL(request.url).origin);
|
|
427
|
+
event.req.set(STATE_KEY, {
|
|
428
|
+
deviceId: token.deviceId,
|
|
429
|
+
key: token.key,
|
|
430
|
+
accessHash: record.accessHash
|
|
431
|
+
});
|
|
432
|
+
return new Request(request, { headers });
|
|
433
|
+
}
|
|
434
|
+
async function after(event) {
|
|
435
|
+
const state = event.req.get(STATE_KEY);
|
|
436
|
+
if (state) return afterBearer(event.request, event.response, state);
|
|
437
|
+
const cookie = event.request.headers.get("cookie");
|
|
438
|
+
if (!_optionalChain([cookie, 'optionalAccess', _17 => _17.includes, 'call', _18 => _18(`${FARM_MOBILE_DEVICE_COOKIE}=`)])) return void 0;
|
|
439
|
+
return afterWebScreen(event.request, event.response);
|
|
440
|
+
}
|
|
441
|
+
async function afterBearer(request, response, state) {
|
|
442
|
+
const changes = readSetCookies(response.headers, now());
|
|
443
|
+
const headers = new Headers(response.headers);
|
|
444
|
+
headers.delete("set-cookie");
|
|
445
|
+
headers.set("cache-control", "private, no-store");
|
|
446
|
+
if (changes.length > 0) {
|
|
447
|
+
const record = await loadDevice(state.deviceId);
|
|
448
|
+
if (record && _chunkSHIWRBFIcjs.farmSecretsMatch.call(void 0, state.accessHash, record.accessHash)) {
|
|
449
|
+
const jar = await openJar(record.jar, state.key, state.deviceId);
|
|
450
|
+
if (jar) {
|
|
451
|
+
const next = applySetCookies(jar, changes);
|
|
452
|
+
const reader = sessionReader();
|
|
453
|
+
let signedOut = false;
|
|
454
|
+
if (reader && changes.some(([, value]) => value === null)) {
|
|
455
|
+
signedOut = await readSession(reader, request.url, next).then(
|
|
456
|
+
async (session) => !session || await sha256(session.id) !== record.sessionHash,
|
|
457
|
+
() => false
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
if (signedOut) await revokeDevice(state.deviceId);
|
|
461
|
+
else
|
|
462
|
+
await saveDevice(state.deviceId, {
|
|
463
|
+
...record,
|
|
464
|
+
jar: await sealJar(next, state.key, state.deviceId)
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return new Response(response.body, {
|
|
470
|
+
status: response.status,
|
|
471
|
+
statusText: response.statusText,
|
|
472
|
+
headers
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
async function afterWebScreen(request, response) {
|
|
476
|
+
const changes = readSetCookies(response.headers, now());
|
|
477
|
+
if (!changes.some(([, value]) => value === null)) return void 0;
|
|
478
|
+
const cookies = readCookies(request.headers.get("cookie"));
|
|
479
|
+
const deviceId = cookies[FARM_MOBILE_DEVICE_COOKIE];
|
|
480
|
+
if (!deviceId || deviceId.length !== 22 || !BASE64URL.test(deviceId)) return void 0;
|
|
481
|
+
const reader = sessionReader();
|
|
482
|
+
if (!reader) return void 0;
|
|
483
|
+
delete cookies[FARM_MOBILE_DEVICE_COOKIE];
|
|
484
|
+
const signedOut = await readSession(
|
|
485
|
+
reader,
|
|
486
|
+
request.url,
|
|
487
|
+
applySetCookies(cookies, changes)
|
|
488
|
+
).then(
|
|
489
|
+
(session) => !session,
|
|
490
|
+
() => false
|
|
491
|
+
);
|
|
492
|
+
if (!signedOut) return void 0;
|
|
493
|
+
await revokeDevice(deviceId);
|
|
494
|
+
const headers = new Headers(response.headers);
|
|
495
|
+
headers.append("set-cookie", markerCookie(request, "", 0));
|
|
496
|
+
return new Response(response.body, {
|
|
497
|
+
status: response.status,
|
|
498
|
+
statusText: response.statusText,
|
|
499
|
+
headers
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
const endpoint = (path, handler) => ({
|
|
503
|
+
path,
|
|
504
|
+
handler: (event) => handler(event.request).catch((error) => {
|
|
505
|
+
if (error instanceof SessionReadError) {
|
|
506
|
+
console.error("[Farm] Mobile session endpoint could not read the session:", error.reason);
|
|
507
|
+
return failure(503, "session_unavailable", "Try again later.");
|
|
508
|
+
}
|
|
509
|
+
throw error;
|
|
510
|
+
})
|
|
511
|
+
});
|
|
512
|
+
return {
|
|
513
|
+
name: FARM_MOBILE_SESSION_PLUGIN,
|
|
514
|
+
// Before app plugins, so their hooks see the signed-in request.
|
|
515
|
+
enforce: "pre",
|
|
516
|
+
runtime: {
|
|
517
|
+
// `before` changes only requests with a mobile bearer, and `after` marks those private.
|
|
518
|
+
// Every other response stays as cacheable as it was.
|
|
519
|
+
cache: "public",
|
|
520
|
+
endpoints: [
|
|
521
|
+
endpoint(`${FARM_MOBILE_SESSION_PATH}/challenge`, challenge),
|
|
522
|
+
endpoint(FARM_MOBILE_SESSION_PATH, issue),
|
|
523
|
+
endpoint(`${FARM_MOBILE_SESSION_PATH}/refresh`, refresh),
|
|
524
|
+
endpoint(`${FARM_MOBILE_SESSION_PATH}/revoke`, revoke)
|
|
525
|
+
],
|
|
526
|
+
before,
|
|
527
|
+
after
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
exports.FARM_MOBILE_SESSION_PLUGIN = FARM_MOBILE_SESSION_PLUGIN; exports.FARM_MOBILE_SESSION_PATH = FARM_MOBILE_SESSION_PATH; exports.FARM_MOBILE_APP_HEADER = FARM_MOBILE_APP_HEADER; exports.FARM_MOBILE_NONCE_HEADER = FARM_MOBILE_NONCE_HEADER; exports.FARM_MOBILE_DEVICE_COOKIE = FARM_MOBILE_DEVICE_COOKIE; exports.parseFarmMobileToken = parseFarmMobileToken; exports.isFarmMobileNativeRequest = isFarmMobileNativeRequest; exports.createFarmMobileSessionPlugin = createFarmMobileSessionPlugin;
|