@frontmcp/sdk 0.4.0 → 0.5.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.
Files changed (558) hide show
  1. package/README.md +30 -18
  2. package/package.json +20 -5
  3. package/src/app/app.registry.d.ts +3 -2
  4. package/src/app/app.registry.js +3 -1
  5. package/src/app/app.registry.js.map +1 -1
  6. package/src/app/instances/app.local.instance.js +2 -2
  7. package/src/app/instances/app.local.instance.js.map +1 -1
  8. package/src/auth/auth.registry.d.ts +34 -2
  9. package/src/auth/auth.registry.js +162 -24
  10. package/src/auth/auth.registry.js.map +1 -1
  11. package/src/auth/auth.utils.js +8 -9
  12. package/src/auth/auth.utils.js.map +1 -1
  13. package/src/auth/authorization/authorization.class.d.ts +125 -0
  14. package/src/auth/authorization/authorization.class.js +224 -0
  15. package/src/auth/authorization/authorization.class.js.map +1 -0
  16. package/src/auth/authorization/authorization.types.d.ts +300 -0
  17. package/src/auth/authorization/authorization.types.js +79 -0
  18. package/src/auth/authorization/authorization.types.js.map +1 -0
  19. package/src/auth/authorization/index.d.ts +5 -0
  20. package/src/auth/authorization/index.js +19 -0
  21. package/src/auth/authorization/index.js.map +1 -0
  22. package/src/auth/authorization/orchestrated.authorization.d.ts +242 -0
  23. package/src/auth/authorization/orchestrated.authorization.js +306 -0
  24. package/src/auth/authorization/orchestrated.authorization.js.map +1 -0
  25. package/src/auth/authorization/public.authorization.d.ts +91 -0
  26. package/src/auth/authorization/public.authorization.js +132 -0
  27. package/src/auth/authorization/public.authorization.js.map +1 -0
  28. package/src/auth/authorization/transparent.authorization.d.ts +130 -0
  29. package/src/auth/authorization/transparent.authorization.js +147 -0
  30. package/src/auth/authorization/transparent.authorization.js.map +1 -0
  31. package/src/auth/consent/consent.types.d.ts +111 -0
  32. package/src/auth/consent/consent.types.js +119 -0
  33. package/src/auth/consent/consent.types.js.map +1 -0
  34. package/src/auth/consent/index.d.ts +1 -0
  35. package/src/auth/consent/index.js +13 -0
  36. package/src/auth/consent/index.js.map +1 -0
  37. package/src/auth/detection/auth-provider-detection.d.ts +84 -0
  38. package/src/auth/detection/auth-provider-detection.js +230 -0
  39. package/src/auth/detection/auth-provider-detection.js.map +1 -0
  40. package/src/auth/detection/index.d.ts +1 -0
  41. package/src/auth/detection/index.js +15 -0
  42. package/src/auth/detection/index.js.map +1 -0
  43. package/src/auth/flows/auth.verify.flow.d.ts +110 -0
  44. package/src/auth/flows/auth.verify.flow.js +379 -0
  45. package/src/auth/flows/auth.verify.flow.js.map +1 -0
  46. package/src/auth/flows/oauth.authorize.flow.d.ts +118 -164
  47. package/src/auth/flows/oauth.authorize.flow.js +701 -33
  48. package/src/auth/flows/oauth.authorize.flow.js.map +1 -1
  49. package/src/auth/flows/oauth.callback.flow.d.ts +117 -0
  50. package/src/auth/flows/oauth.callback.flow.js +357 -0
  51. package/src/auth/flows/oauth.callback.flow.js.map +1 -0
  52. package/src/auth/flows/oauth.register.flow.d.ts +32 -125
  53. package/src/auth/flows/oauth.token.flow.d.ts +52 -154
  54. package/src/auth/flows/oauth.token.flow.js +193 -55
  55. package/src/auth/flows/oauth.token.flow.js.map +1 -1
  56. package/src/auth/flows/session.verify.flow.d.ts +66 -321
  57. package/src/auth/flows/session.verify.flow.js +107 -18
  58. package/src/auth/flows/session.verify.flow.js.map +1 -1
  59. package/src/auth/flows/well-known.jwks.flow.d.ts +34 -205
  60. package/src/auth/flows/well-known.jwks.flow.js +15 -8
  61. package/src/auth/flows/well-known.jwks.flow.js.map +1 -1
  62. package/src/auth/flows/well-known.oauth-authorization-server.flow.d.ts +48 -223
  63. package/src/auth/flows/well-known.oauth-authorization-server.flow.js +2 -3
  64. package/src/auth/flows/well-known.oauth-authorization-server.flow.js.map +1 -1
  65. package/src/auth/flows/well-known.prm.flow.d.ts +19 -120
  66. package/src/auth/flows/well-known.prm.flow.js +3 -4
  67. package/src/auth/flows/well-known.prm.flow.js.map +1 -1
  68. package/src/auth/instances/instance.local-primary-auth.d.ts +91 -4
  69. package/src/auth/instances/instance.local-primary-auth.js +236 -6
  70. package/src/auth/instances/instance.local-primary-auth.js.map +1 -1
  71. package/src/auth/instances/instance.remote-primary-auth.d.ts +4 -3
  72. package/src/auth/instances/instance.remote-primary-auth.js +2 -2
  73. package/src/auth/instances/instance.remote-primary-auth.js.map +1 -1
  74. package/src/auth/session/authorization-vault.d.ts +611 -0
  75. package/src/auth/session/authorization-vault.js +817 -0
  76. package/src/auth/session/authorization-vault.js.map +1 -0
  77. package/src/auth/session/authorization.store.d.ts +301 -0
  78. package/src/auth/session/authorization.store.js +323 -0
  79. package/src/auth/session/authorization.store.js.map +1 -0
  80. package/src/auth/session/encrypted-authorization-vault.d.ts +181 -0
  81. package/src/auth/session/encrypted-authorization-vault.js +493 -0
  82. package/src/auth/session/encrypted-authorization-vault.js.map +1 -0
  83. package/src/auth/session/index.d.ts +4 -4
  84. package/src/auth/session/index.js +11 -7
  85. package/src/auth/session/index.js.map +1 -1
  86. package/src/auth/session/session.schema.d.ts +1 -1
  87. package/src/auth/session/session.service.d.ts +1 -1
  88. package/src/auth/session/transport-session.manager.d.ts +101 -0
  89. package/src/auth/session/transport-session.manager.js +300 -0
  90. package/src/auth/session/transport-session.manager.js.map +1 -0
  91. package/src/auth/session/transport-session.types.d.ts +457 -0
  92. package/src/auth/session/transport-session.types.js +110 -0
  93. package/src/auth/session/transport-session.types.js.map +1 -0
  94. package/src/auth/session/utils/session-id.utils.d.ts +14 -2
  95. package/src/auth/session/utils/session-id.utils.js +68 -19
  96. package/src/auth/session/utils/session-id.utils.js.map +1 -1
  97. package/src/auth/session/vault-encryption.d.ts +189 -0
  98. package/src/auth/session/vault-encryption.js +263 -0
  99. package/src/auth/session/vault-encryption.js.map +1 -0
  100. package/src/auth/ui/base-layout.d.ts +188 -0
  101. package/src/auth/ui/base-layout.js +292 -0
  102. package/src/auth/ui/base-layout.js.map +1 -0
  103. package/src/auth/ui/htmx-templates.d.ts +135 -0
  104. package/src/auth/ui/htmx-templates.js +433 -0
  105. package/src/auth/ui/htmx-templates.js.map +1 -0
  106. package/src/auth/ui/index.d.ts +11 -0
  107. package/src/auth/ui/index.js +35 -0
  108. package/src/auth/ui/index.js.map +1 -0
  109. package/src/auth/utils/audience.validator.d.ts +129 -0
  110. package/src/auth/utils/audience.validator.js +196 -0
  111. package/src/auth/utils/audience.validator.js.map +1 -0
  112. package/src/auth/utils/index.d.ts +2 -0
  113. package/src/auth/utils/index.js +7 -0
  114. package/src/auth/utils/index.js.map +1 -0
  115. package/src/auth/utils/www-authenticate.utils.d.ts +97 -0
  116. package/src/auth/utils/www-authenticate.utils.js +183 -0
  117. package/src/auth/utils/www-authenticate.utils.js.map +1 -0
  118. package/src/common/common.schema.d.ts +2 -16
  119. package/src/common/constants.d.ts +3 -0
  120. package/src/common/constants.js +6 -1
  121. package/src/common/constants.js.map +1 -1
  122. package/src/common/decorators/decorator-utils.d.ts +131 -0
  123. package/src/common/decorators/decorator-utils.js +195 -0
  124. package/src/common/decorators/decorator-utils.js.map +1 -0
  125. package/src/common/decorators/front-mcp.decorator.js +3 -2
  126. package/src/common/decorators/front-mcp.decorator.js.map +1 -1
  127. package/src/common/decorators/hook.decorator.d.ts +58 -2
  128. package/src/common/decorators/hook.decorator.js +127 -17
  129. package/src/common/decorators/hook.decorator.js.map +1 -1
  130. package/src/common/decorators/plugin.decorator.d.ts +1 -1
  131. package/src/common/decorators/plugin.decorator.js +11 -10
  132. package/src/common/decorators/plugin.decorator.js.map +1 -1
  133. package/src/common/decorators/resource.decorator.d.ts +32 -3
  134. package/src/common/decorators/resource.decorator.js +46 -4
  135. package/src/common/decorators/resource.decorator.js.map +1 -1
  136. package/src/common/decorators/tool.decorator.d.ts +54 -5
  137. package/src/common/decorators/tool.decorator.js.map +1 -1
  138. package/src/common/dynamic/dynamic.plugin.d.ts +22 -11
  139. package/src/common/dynamic/dynamic.plugin.js +7 -1
  140. package/src/common/dynamic/dynamic.plugin.js.map +1 -1
  141. package/src/common/entries/prompt.entry.d.ts +46 -2
  142. package/src/common/entries/prompt.entry.js +10 -0
  143. package/src/common/entries/prompt.entry.js.map +1 -1
  144. package/src/common/entries/resource.entry.d.ts +69 -6
  145. package/src/common/entries/resource.entry.js +27 -3
  146. package/src/common/entries/resource.entry.js.map +1 -1
  147. package/src/common/entries/scope.entry.d.ts +5 -1
  148. package/src/common/entries/scope.entry.js +3 -3
  149. package/src/common/entries/scope.entry.js.map +1 -1
  150. package/src/common/flow/flow.utils.d.ts +56 -0
  151. package/src/common/flow/flow.utils.js +96 -0
  152. package/src/common/flow/flow.utils.js.map +1 -0
  153. package/src/common/index.d.ts +2 -2
  154. package/src/common/index.js +2 -2
  155. package/src/common/index.js.map +1 -1
  156. package/src/common/interfaces/execution-context.interface.d.ts +59 -0
  157. package/src/common/interfaces/execution-context.interface.js +81 -0
  158. package/src/common/interfaces/execution-context.interface.js.map +1 -0
  159. package/src/common/interfaces/flow.interface.d.ts +1 -1
  160. package/src/common/interfaces/flow.interface.js.map +1 -1
  161. package/src/common/interfaces/index.d.ts +1 -0
  162. package/src/common/interfaces/index.js +1 -0
  163. package/src/common/interfaces/index.js.map +1 -1
  164. package/src/common/interfaces/internal/primary-auth-provider.interface.d.ts +17 -2
  165. package/src/common/interfaces/internal/primary-auth-provider.interface.js +52 -4
  166. package/src/common/interfaces/internal/primary-auth-provider.interface.js.map +1 -1
  167. package/src/common/interfaces/internal/registry.interface.d.ts +16 -2
  168. package/src/common/interfaces/internal/registry.interface.js.map +1 -1
  169. package/src/common/interfaces/plugin.interface.js.map +1 -1
  170. package/src/common/interfaces/prompt.interface.d.ts +53 -4
  171. package/src/common/interfaces/prompt.interface.js +78 -0
  172. package/src/common/interfaces/prompt.interface.js.map +1 -1
  173. package/src/common/interfaces/resource.interface.d.ts +47 -17
  174. package/src/common/interfaces/resource.interface.js +53 -0
  175. package/src/common/interfaces/resource.interface.js.map +1 -1
  176. package/src/common/interfaces/tool.interface.d.ts +39 -22
  177. package/src/common/interfaces/tool.interface.js +61 -34
  178. package/src/common/interfaces/tool.interface.js.map +1 -1
  179. package/src/common/metadata/adapter.metadata.d.ts +1 -9
  180. package/src/common/metadata/app.metadata.d.ts +425 -730
  181. package/src/common/metadata/auth-provider.metadata.d.ts +2 -12
  182. package/src/common/metadata/flow.metadata.d.ts +10 -25
  183. package/src/common/metadata/front-mcp.metadata.d.ts +602 -1023
  184. package/src/common/metadata/front-mcp.metadata.js +6 -4
  185. package/src/common/metadata/front-mcp.metadata.js.map +1 -1
  186. package/src/common/metadata/hook.metadata.d.ts +1 -1
  187. package/src/common/metadata/hook.metadata.js.map +1 -1
  188. package/src/common/metadata/index.d.ts +1 -0
  189. package/src/common/metadata/index.js +1 -0
  190. package/src/common/metadata/index.js.map +1 -1
  191. package/src/common/metadata/logger.metadata.d.ts +1 -9
  192. package/src/common/metadata/plugin.metadata.d.ts +8 -30
  193. package/src/common/metadata/prompt.metadata.d.ts +4 -161
  194. package/src/common/metadata/provider.metadata.d.ts +2 -12
  195. package/src/common/metadata/resource.metadata.d.ts +6 -98
  196. package/src/common/metadata/resource.metadata.js +15 -6
  197. package/src/common/metadata/resource.metadata.js.map +1 -1
  198. package/src/common/metadata/tool-ui.metadata.d.ts +10 -0
  199. package/src/common/metadata/tool-ui.metadata.js +12 -0
  200. package/src/common/metadata/tool-ui.metadata.js.map +1 -0
  201. package/src/common/metadata/tool.metadata.d.ts +78 -199
  202. package/src/common/metadata/tool.metadata.js +11 -14
  203. package/src/common/metadata/tool.metadata.js.map +1 -1
  204. package/src/common/providers/base-config.provider.d.ts +84 -0
  205. package/src/common/providers/base-config.provider.js +128 -0
  206. package/src/common/providers/base-config.provider.js.map +1 -0
  207. package/src/common/records/plugin.record.d.ts +5 -6
  208. package/src/common/records/plugin.record.js.map +1 -1
  209. package/src/common/records/prompt.record.js.map +1 -1
  210. package/src/common/records/resource.record.d.ts +17 -1
  211. package/src/common/records/resource.record.js +12 -6
  212. package/src/common/records/resource.record.js.map +1 -1
  213. package/src/common/records/tool.record.js.map +1 -1
  214. package/src/common/schemas/annotated-class.schema.d.ts +9 -9
  215. package/src/common/schemas/annotated-class.schema.js +92 -27
  216. package/src/common/schemas/annotated-class.schema.js.map +1 -1
  217. package/src/common/schemas/http-input.schema.d.ts +6 -30
  218. package/src/common/schemas/http-output.schema.d.ts +326 -1630
  219. package/src/common/schemas/http-output.schema.js +39 -1
  220. package/src/common/schemas/http-output.schema.js.map +1 -1
  221. package/src/common/tokens/front-mcp.tokens.js +4 -1
  222. package/src/common/tokens/front-mcp.tokens.js.map +1 -1
  223. package/src/common/tokens/resource.tokens.d.ts +2 -0
  224. package/src/common/tokens/resource.tokens.js +4 -1
  225. package/src/common/tokens/resource.tokens.js.map +1 -1
  226. package/src/common/tokens/tool.tokens.d.ts +2 -0
  227. package/src/common/tokens/tool.tokens.js +2 -0
  228. package/src/common/tokens/tool.tokens.js.map +1 -1
  229. package/src/common/types/auth/jwt.types.d.ts +5 -31
  230. package/src/common/types/auth/session.types.d.ts +97 -192
  231. package/src/common/types/auth/session.types.js +24 -11
  232. package/src/common/types/auth/session.types.js.map +1 -1
  233. package/src/common/types/options/auth.options.d.ts +1013 -490
  234. package/src/common/types/options/auth.options.js +554 -36
  235. package/src/common/types/options/auth.options.js.map +1 -1
  236. package/src/common/types/options/http.options.d.ts +1 -9
  237. package/src/common/types/options/logging.options.d.ts +7 -13
  238. package/src/common/types/options/logging.options.js +4 -0
  239. package/src/common/types/options/logging.options.js.map +1 -1
  240. package/src/common/types/options/server-info.options.d.ts +3 -31
  241. package/src/common/types/options/session.options.d.ts +90 -10
  242. package/src/common/types/options/session.options.js +26 -3
  243. package/src/common/types/options/session.options.js.map +1 -1
  244. package/src/common/utils/decide-request-intent.utils.d.ts +8 -46
  245. package/src/common/utils/decide-request-intent.utils.js +88 -23
  246. package/src/common/utils/decide-request-intent.utils.js.map +1 -1
  247. package/src/completion/flows/complete.flow.d.ts +74 -0
  248. package/src/completion/flows/complete.flow.js +199 -0
  249. package/src/completion/flows/complete.flow.js.map +1 -0
  250. package/src/errors/authorization-required.error.d.ts +189 -0
  251. package/src/errors/authorization-required.error.js +274 -0
  252. package/src/errors/authorization-required.error.js.map +1 -0
  253. package/src/errors/index.d.ts +2 -1
  254. package/src/errors/index.js +17 -1
  255. package/src/errors/index.js.map +1 -1
  256. package/src/errors/mcp.error.d.ts +101 -1
  257. package/src/errors/mcp.error.js +147 -2
  258. package/src/errors/mcp.error.js.map +1 -1
  259. package/src/flows/flow.instance.js +4 -3
  260. package/src/flows/flow.instance.js.map +1 -1
  261. package/src/flows/flow.registry.js.map +1 -1
  262. package/src/flows/flow.stages.js +14 -11
  263. package/src/flows/flow.stages.js.map +1 -1
  264. package/src/front-mcp/front-mcp.providers.d.ts +464 -102
  265. package/src/front-mcp/front-mcp.providers.js +3 -5
  266. package/src/front-mcp/front-mcp.providers.js.map +1 -1
  267. package/src/hooks/hook.instance.d.ts +1 -1
  268. package/src/hooks/hook.instance.js +5 -2
  269. package/src/hooks/hook.instance.js.map +1 -1
  270. package/src/hooks/hook.registry.js +7 -5
  271. package/src/hooks/hook.registry.js.map +1 -1
  272. package/src/index.d.ts +28 -9
  273. package/src/index.js +5 -1
  274. package/src/index.js.map +1 -1
  275. package/src/logger/instances/instance.logger.js +3 -2
  276. package/src/logger/instances/instance.logger.js.map +1 -1
  277. package/src/logger/logger.registry.js +7 -2
  278. package/src/logger/logger.registry.js.map +1 -1
  279. package/src/logging/flows/set-level.flow.d.ts +62 -0
  280. package/src/logging/flows/set-level.flow.js +108 -0
  281. package/src/logging/flows/set-level.flow.js.map +1 -0
  282. package/src/mcp-apps/csp.d.ts +111 -0
  283. package/src/mcp-apps/csp.js +267 -0
  284. package/src/mcp-apps/csp.js.map +1 -0
  285. package/src/mcp-apps/index.d.ts +23 -0
  286. package/src/mcp-apps/index.js +91 -0
  287. package/src/mcp-apps/index.js.map +1 -0
  288. package/src/mcp-apps/schemas.d.ts +403 -0
  289. package/src/mcp-apps/schemas.js +345 -0
  290. package/src/mcp-apps/schemas.js.map +1 -0
  291. package/src/mcp-apps/template.d.ts +94 -0
  292. package/src/mcp-apps/template.js +419 -0
  293. package/src/mcp-apps/template.js.map +1 -0
  294. package/src/mcp-apps/types.d.ts +323 -0
  295. package/src/mcp-apps/types.js +59 -0
  296. package/src/mcp-apps/types.js.map +1 -0
  297. package/src/notification/index.d.ts +1 -0
  298. package/src/notification/index.js +13 -0
  299. package/src/notification/index.js.map +1 -0
  300. package/src/notification/notification.service.d.ts +378 -0
  301. package/src/notification/notification.service.js +727 -0
  302. package/src/notification/notification.service.js.map +1 -0
  303. package/src/plugin/plugin.registry.js +12 -9
  304. package/src/plugin/plugin.registry.js.map +1 -1
  305. package/src/prompt/flows/get-prompt.flow.d.ts +153 -0
  306. package/src/prompt/flows/get-prompt.flow.js +214 -0
  307. package/src/prompt/flows/get-prompt.flow.js.map +1 -0
  308. package/src/prompt/flows/prompts-list.flow.d.ts +67 -0
  309. package/src/prompt/flows/prompts-list.flow.js +176 -0
  310. package/src/prompt/flows/prompts-list.flow.js.map +1 -0
  311. package/src/prompt/index.d.ts +7 -0
  312. package/src/prompt/index.js +17 -0
  313. package/src/prompt/index.js.map +1 -0
  314. package/src/prompt/prompt.events.d.ts +17 -0
  315. package/src/prompt/prompt.events.js +25 -0
  316. package/src/prompt/prompt.events.js.map +1 -0
  317. package/src/prompt/prompt.instance.d.ts +30 -0
  318. package/src/prompt/prompt.instance.js +120 -0
  319. package/src/prompt/prompt.instance.js.map +1 -0
  320. package/src/prompt/prompt.registry.d.ts +79 -12
  321. package/src/prompt/prompt.registry.js +360 -15
  322. package/src/prompt/prompt.registry.js.map +1 -1
  323. package/src/prompt/prompt.types.d.ts +26 -0
  324. package/src/prompt/prompt.types.js +11 -0
  325. package/src/prompt/prompt.types.js.map +1 -0
  326. package/src/prompt/prompt.utils.d.ts +26 -0
  327. package/src/prompt/prompt.utils.js +136 -0
  328. package/src/prompt/prompt.utils.js.map +1 -0
  329. package/src/provider/provider.registry.d.ts +12 -5
  330. package/src/provider/provider.registry.js +30 -138
  331. package/src/provider/provider.registry.js.map +1 -1
  332. package/src/regsitry/registry.base.d.ts +1 -1
  333. package/src/regsitry/registry.base.js.map +1 -1
  334. package/src/resource/flows/read-resource.flow.d.ts +91 -0
  335. package/src/resource/flows/read-resource.flow.js +270 -0
  336. package/src/resource/flows/read-resource.flow.js.map +1 -0
  337. package/src/resource/flows/resource-templates-list.flow.d.ts +64 -0
  338. package/src/resource/flows/resource-templates-list.flow.js +191 -0
  339. package/src/resource/flows/resource-templates-list.flow.js.map +1 -0
  340. package/src/resource/flows/resources-list.flow.d.ts +64 -0
  341. package/src/resource/flows/resources-list.flow.js +196 -0
  342. package/src/resource/flows/resources-list.flow.js.map +1 -0
  343. package/src/resource/flows/subscribe-resource.flow.d.ts +45 -0
  344. package/src/resource/flows/subscribe-resource.flow.js +123 -0
  345. package/src/resource/flows/subscribe-resource.flow.js.map +1 -0
  346. package/src/resource/flows/unsubscribe-resource.flow.d.ts +44 -0
  347. package/src/resource/flows/unsubscribe-resource.flow.js +107 -0
  348. package/src/resource/flows/unsubscribe-resource.flow.js.map +1 -0
  349. package/src/resource/index.d.ts +8 -0
  350. package/src/resource/index.js +20 -0
  351. package/src/resource/index.js.map +1 -0
  352. package/src/resource/resource.events.d.ts +24 -0
  353. package/src/resource/resource.events.js +17 -0
  354. package/src/resource/resource.events.js.map +1 -0
  355. package/src/resource/resource.instance.d.ts +35 -0
  356. package/src/resource/resource.instance.js +163 -0
  357. package/src/resource/resource.instance.js.map +1 -0
  358. package/src/resource/resource.registry.d.ts +106 -12
  359. package/src/resource/resource.registry.js +449 -13
  360. package/src/resource/resource.registry.js.map +1 -1
  361. package/src/resource/resource.types.d.ts +35 -0
  362. package/src/resource/resource.types.js +11 -0
  363. package/src/resource/resource.types.js.map +1 -0
  364. package/src/resource/resource.utils.d.ts +30 -0
  365. package/src/resource/resource.utils.js +151 -0
  366. package/src/resource/resource.utils.js.map +1 -0
  367. package/src/scope/flows/http.request.flow.d.ts +48 -330
  368. package/src/scope/flows/http.request.flow.js +306 -78
  369. package/src/scope/flows/http.request.flow.js.map +1 -1
  370. package/src/scope/scope.instance.d.ts +12 -0
  371. package/src/scope/scope.instance.js +145 -15
  372. package/src/scope/scope.instance.js.map +1 -1
  373. package/src/tool/flows/call-tool.flow.d.ts +64 -1110
  374. package/src/tool/flows/call-tool.flow.js +303 -15
  375. package/src/tool/flows/call-tool.flow.js.map +1 -1
  376. package/src/tool/flows/tools-list.flow.d.ts +32 -473
  377. package/src/tool/flows/tools-list.flow.js +111 -10
  378. package/src/tool/flows/tools-list.flow.js.map +1 -1
  379. package/src/tool/tool.events.d.ts +8 -1
  380. package/src/tool/tool.events.js.map +1 -1
  381. package/src/tool/tool.instance.d.ts +3 -1
  382. package/src/tool/tool.instance.js +17 -3
  383. package/src/tool/tool.instance.js.map +1 -1
  384. package/src/tool/tool.registry.d.ts +7 -1
  385. package/src/tool/tool.registry.js +26 -10
  386. package/src/tool/tool.registry.js.map +1 -1
  387. package/src/tool/tool.types.d.ts +4 -4
  388. package/src/tool/tool.types.js.map +1 -1
  389. package/src/tool/tool.utils.d.ts +3 -12
  390. package/src/tool/tool.utils.js +39 -193
  391. package/src/tool/tool.utils.js.map +1 -1
  392. package/src/tool/ui/index.d.ts +22 -0
  393. package/src/tool/ui/index.js +63 -0
  394. package/src/tool/ui/index.js.map +1 -0
  395. package/src/tool/ui/platform-adapters.d.ts +10 -0
  396. package/src/tool/ui/platform-adapters.js +18 -0
  397. package/src/tool/ui/platform-adapters.js.map +1 -0
  398. package/src/tool/ui/template-helpers.d.ts +46 -0
  399. package/src/tool/ui/template-helpers.js +112 -0
  400. package/src/tool/ui/template-helpers.js.map +1 -0
  401. package/src/tool/ui/ui-resource-template.d.ts +34 -0
  402. package/src/tool/ui/ui-resource-template.js +64 -0
  403. package/src/tool/ui/ui-resource-template.js.map +1 -0
  404. package/src/tool/ui/ui-resource.handler.d.ts +74 -0
  405. package/src/tool/ui/ui-resource.handler.js +129 -0
  406. package/src/tool/ui/ui-resource.handler.js.map +1 -0
  407. package/src/transport/adapters/transport.local.adapter.d.ts +2 -2
  408. package/src/transport/adapters/transport.local.adapter.js +28 -7
  409. package/src/transport/adapters/transport.local.adapter.js.map +1 -1
  410. package/src/transport/adapters/transport.sse.adapter.d.ts +2 -2
  411. package/src/transport/adapters/transport.sse.adapter.js +4 -3
  412. package/src/transport/adapters/transport.sse.adapter.js.map +1 -1
  413. package/src/transport/adapters/transport.streamable-http.adapter.d.ts +10 -3
  414. package/src/transport/adapters/transport.streamable-http.adapter.js +54 -8
  415. package/src/transport/adapters/transport.streamable-http.adapter.js.map +1 -1
  416. package/src/transport/flows/handle.sse.flow.d.ts +29 -63
  417. package/src/transport/flows/handle.sse.flow.js +78 -10
  418. package/src/transport/flows/handle.sse.flow.js.map +1 -1
  419. package/src/transport/flows/handle.stateless-http.flow.d.ts +29 -0
  420. package/src/transport/flows/handle.stateless-http.flow.js +102 -0
  421. package/src/transport/flows/handle.stateless-http.flow.js.map +1 -0
  422. package/src/transport/flows/handle.streamable-http.flow.d.ts +32 -64
  423. package/src/transport/flows/handle.streamable-http.flow.js +158 -26
  424. package/src/transport/flows/handle.streamable-http.flow.js.map +1 -1
  425. package/src/transport/legacy/legacy.sse.tranporter.d.ts +9 -0
  426. package/src/transport/legacy/legacy.sse.tranporter.js +17 -2
  427. package/src/transport/legacy/legacy.sse.tranporter.js.map +1 -1
  428. package/src/transport/mcp-handlers/call-tool-request.handler.js +27 -1
  429. package/src/transport/mcp-handlers/call-tool-request.handler.js.map +1 -1
  430. package/src/transport/mcp-handlers/complete-request.handler.d.ts +69 -0
  431. package/src/transport/mcp-handlers/complete-request.handler.js +11 -0
  432. package/src/transport/mcp-handlers/complete-request.handler.js.map +1 -0
  433. package/src/transport/mcp-handlers/get-prompt-request.handler.d.ts +87 -0
  434. package/src/transport/mcp-handlers/get-prompt-request.handler.js +11 -0
  435. package/src/transport/mcp-handlers/get-prompt-request.handler.js.map +1 -0
  436. package/src/transport/mcp-handlers/index.d.ts +517 -208
  437. package/src/transport/mcp-handlers/index.js +39 -2
  438. package/src/transport/mcp-handlers/index.js.map +1 -1
  439. package/src/transport/mcp-handlers/initialize-request.handler.d.ts +1 -1
  440. package/src/transport/mcp-handlers/initialize-request.handler.js +73 -7
  441. package/src/transport/mcp-handlers/initialize-request.handler.js.map +1 -1
  442. package/src/transport/mcp-handlers/list-prompts-request.handler.d.ts +54 -0
  443. package/src/transport/mcp-handlers/list-prompts-request.handler.js +11 -0
  444. package/src/transport/mcp-handlers/list-prompts-request.handler.js.map +1 -0
  445. package/src/transport/mcp-handlers/list-resource-templates-request.handler.d.ts +51 -0
  446. package/src/transport/mcp-handlers/list-resource-templates-request.handler.js +12 -0
  447. package/src/transport/mcp-handlers/list-resource-templates-request.handler.js.map +1 -0
  448. package/src/transport/mcp-handlers/list-resources-request.handler.d.ts +51 -0
  449. package/src/transport/mcp-handlers/list-resources-request.handler.js +12 -0
  450. package/src/transport/mcp-handlers/list-resources-request.handler.js.map +1 -0
  451. package/src/transport/mcp-handlers/list-tools-request.handler.d.ts +19 -146
  452. package/src/transport/mcp-handlers/logging-set-level-request.handler.d.ts +46 -0
  453. package/src/transport/mcp-handlers/logging-set-level-request.handler.js +34 -0
  454. package/src/transport/mcp-handlers/logging-set-level-request.handler.js.map +1 -0
  455. package/src/transport/mcp-handlers/mcp-handlers.types.d.ts +3 -7
  456. package/src/transport/mcp-handlers/mcp-handlers.types.js.map +1 -1
  457. package/src/transport/mcp-handlers/read-resource-request.handler.d.ts +46 -0
  458. package/src/transport/mcp-handlers/read-resource-request.handler.js +12 -0
  459. package/src/transport/mcp-handlers/read-resource-request.handler.js.map +1 -0
  460. package/src/transport/mcp-handlers/roots-list-changed-notification.handler.d.ts +11 -0
  461. package/src/transport/mcp-handlers/roots-list-changed-notification.handler.js +26 -0
  462. package/src/transport/mcp-handlers/roots-list-changed-notification.handler.js.map +1 -0
  463. package/src/transport/mcp-handlers/subscribe-request.handler.d.ts +37 -0
  464. package/src/transport/mcp-handlers/subscribe-request.handler.js +34 -0
  465. package/src/transport/mcp-handlers/subscribe-request.handler.js.map +1 -0
  466. package/src/transport/mcp-handlers/unsubscribe-request.handler.d.ts +37 -0
  467. package/src/transport/mcp-handlers/unsubscribe-request.handler.js +34 -0
  468. package/src/transport/mcp-handlers/unsubscribe-request.handler.js.map +1 -0
  469. package/src/transport/transport.local.js +7 -2
  470. package/src/transport/transport.local.js.map +1 -1
  471. package/src/transport/transport.registry.d.ts +30 -0
  472. package/src/transport/transport.registry.js +84 -1
  473. package/src/transport/transport.registry.js.map +1 -1
  474. package/src/transport/transport.types.d.ts +3 -3
  475. package/src/transport/transport.types.js.map +1 -1
  476. package/src/utils/content.utils.d.ts +48 -0
  477. package/src/utils/content.utils.js +194 -0
  478. package/src/utils/content.utils.js.map +1 -0
  479. package/src/utils/index.d.ts +8 -0
  480. package/src/utils/index.js +55 -0
  481. package/src/utils/index.js.map +1 -0
  482. package/src/utils/lineage.utils.d.ts +40 -0
  483. package/src/utils/lineage.utils.js +82 -0
  484. package/src/utils/lineage.utils.js.map +1 -0
  485. package/src/utils/naming.utils.d.ts +46 -0
  486. package/src/utils/naming.utils.js +136 -0
  487. package/src/utils/naming.utils.js.map +1 -0
  488. package/src/utils/types.utils.d.ts +2 -2
  489. package/src/utils/types.utils.js.map +1 -1
  490. package/src/utils/uri-template.utils.d.ts +57 -0
  491. package/src/utils/uri-template.utils.js +113 -0
  492. package/src/utils/uri-template.utils.js.map +1 -0
  493. package/src/utils/uri-validation.utils.d.ts +40 -0
  494. package/src/utils/uri-validation.utils.js +76 -0
  495. package/src/utils/uri-validation.utils.js.map +1 -0
  496. package/src/__test-utils__/fixtures/hook.fixtures.d.ts +0 -46
  497. package/src/__test-utils__/fixtures/hook.fixtures.js +0 -114
  498. package/src/__test-utils__/fixtures/hook.fixtures.js.map +0 -1
  499. package/src/__test-utils__/fixtures/index.d.ts +0 -7
  500. package/src/__test-utils__/fixtures/index.js +0 -11
  501. package/src/__test-utils__/fixtures/index.js.map +0 -1
  502. package/src/__test-utils__/fixtures/plugin.fixtures.d.ts +0 -46
  503. package/src/__test-utils__/fixtures/plugin.fixtures.js +0 -127
  504. package/src/__test-utils__/fixtures/plugin.fixtures.js.map +0 -1
  505. package/src/__test-utils__/fixtures/provider.fixtures.d.ts +0 -69
  506. package/src/__test-utils__/fixtures/provider.fixtures.js +0 -131
  507. package/src/__test-utils__/fixtures/provider.fixtures.js.map +0 -1
  508. package/src/__test-utils__/fixtures/scope.fixtures.d.ts +0 -14
  509. package/src/__test-utils__/fixtures/scope.fixtures.js +0 -59
  510. package/src/__test-utils__/fixtures/scope.fixtures.js.map +0 -1
  511. package/src/__test-utils__/fixtures/tool.fixtures.d.ts +0 -36
  512. package/src/__test-utils__/fixtures/tool.fixtures.js +0 -91
  513. package/src/__test-utils__/fixtures/tool.fixtures.js.map +0 -1
  514. package/src/__test-utils__/helpers/assertion.helpers.d.ts +0 -45
  515. package/src/__test-utils__/helpers/assertion.helpers.js +0 -153
  516. package/src/__test-utils__/helpers/assertion.helpers.js.map +0 -1
  517. package/src/__test-utils__/helpers/async.helpers.d.ts +0 -48
  518. package/src/__test-utils__/helpers/async.helpers.js +0 -112
  519. package/src/__test-utils__/helpers/async.helpers.js.map +0 -1
  520. package/src/__test-utils__/helpers/index.d.ts +0 -6
  521. package/src/__test-utils__/helpers/index.js +0 -10
  522. package/src/__test-utils__/helpers/index.js.map +0 -1
  523. package/src/__test-utils__/helpers/setup.helpers.d.ts +0 -54
  524. package/src/__test-utils__/helpers/setup.helpers.js +0 -106
  525. package/src/__test-utils__/helpers/setup.helpers.js.map +0 -1
  526. package/src/__test-utils__/index.d.ts +0 -9
  527. package/src/__test-utils__/index.js +0 -14
  528. package/src/__test-utils__/index.js.map +0 -1
  529. package/src/__test-utils__/mocks/flow-instance.mock.d.ts +0 -50
  530. package/src/__test-utils__/mocks/flow-instance.mock.js +0 -72
  531. package/src/__test-utils__/mocks/flow-instance.mock.js.map +0 -1
  532. package/src/__test-utils__/mocks/hook-registry.mock.d.ts +0 -25
  533. package/src/__test-utils__/mocks/hook-registry.mock.js +0 -65
  534. package/src/__test-utils__/mocks/hook-registry.mock.js.map +0 -1
  535. package/src/__test-utils__/mocks/index.d.ts +0 -8
  536. package/src/__test-utils__/mocks/index.js +0 -12
  537. package/src/__test-utils__/mocks/index.js.map +0 -1
  538. package/src/__test-utils__/mocks/plugin-registry.mock.d.ts +0 -43
  539. package/src/__test-utils__/mocks/plugin-registry.mock.js +0 -70
  540. package/src/__test-utils__/mocks/plugin-registry.mock.js.map +0 -1
  541. package/src/__test-utils__/mocks/provider-registry.mock.d.ts +0 -39
  542. package/src/__test-utils__/mocks/provider-registry.mock.js +0 -72
  543. package/src/__test-utils__/mocks/provider-registry.mock.js.map +0 -1
  544. package/src/__test-utils__/mocks/tool-registry.mock.d.ts +0 -43
  545. package/src/__test-utils__/mocks/tool-registry.mock.js +0 -79
  546. package/src/__test-utils__/mocks/tool-registry.mock.js.map +0 -1
  547. package/src/auth/path.utils.d.ts +0 -20
  548. package/src/auth/path.utils.js +0 -71
  549. package/src/auth/path.utils.js.map +0 -1
  550. package/src/common/decorators-old/async-with.decorator.d.ts +0 -10
  551. package/src/common/decorators-old/async-with.decorator.js +0 -24
  552. package/src/common/decorators-old/async-with.decorator.js.map +0 -1
  553. package/src/common/decorators-old/auth-hook.decorator.d.ts +0 -14
  554. package/src/common/decorators-old/auth-hook.decorator.js +0 -27
  555. package/src/common/decorators-old/auth-hook.decorator.js.map +0 -1
  556. package/src/common/decorators-old/session-hook.decorator.d.ts +0 -14
  557. package/src/common/decorators-old/session-hook.decorator.js +0 -27
  558. package/src/common/decorators-old/session-hook.decorator.js.map +0 -1
@@ -33,7 +33,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
33
33
  const tslib_1 = require("tslib");
34
34
  /**
35
35
  *
36
- * OAuth 2.0 Device Authorization Grant (device code flow)
36
+ * OAuth 2.0 Device Authorization Grant ("device code flow")
37
37
  * Who does what (at a glance)
38
38
  *
39
39
  * Device/TV/CLI (no browser)
@@ -43,101 +43,215 @@ const tslib_1 = require("tslib");
43
43
  * Visits the given verification_uri and authenticates using your normal OAuth login (whatever you already have). No new UI required beyond two tiny endpoints.
44
44
  *
45
45
  * Auth Server (you)
46
- * Stores the device transaction and, after the user authenticates, marks it as approved so the devices /oauth/token polling succeeds.
46
+ * Stores the device transaction and, after the user authenticates, marks it as approved so the device's /oauth/token polling succeeds.
47
47
  *
48
- * Endpoints you need (only two new ones)
48
+ * Endpoints you need (only two "new" ones)
49
49
  *
50
50
  * POST /oauth/device_authorization ✅ (device calls)
51
51
  *
52
52
  * POST /oauth/token with grant urn:ietf:params:oauth:grant-type:device_code ✅ (device polls)
53
53
  *
54
- * GET /activate ➜ UI handler (user lands here from verification_uri — this just redirects into your existing /oauth/authorize)
54
+ * GET /activate ➜ "UI handler" (user lands here from verification_uri — this just redirects into your existing /oauth/authorize)
55
55
  *
56
- * GET /activate/callback ➜ UI handler (your existing flow returns here after the user logs in; you flip the device record to approved and show a basic All set page)
56
+ * GET /activate/callback ➜ "UI handler" (your existing flow returns here after the user logs in; you flip the device record to approved and show a basic "All set" page)
57
57
  *
58
- * Thats it. No pages with complex consent screens are required; reuse your normal /oauth/authorize
58
+ * That's it. No pages with complex consent screens are required; reuse your normal /oauth/authorize
59
59
  */
60
60
  const common_1 = require("../../common");
61
61
  const zod_1 = require("zod");
62
62
  const crypto_1 = require("crypto");
63
63
  const inputSchema = common_1.httpInputSchema;
64
64
  // RFC 7636 PKCE: code_verifier is 43–128 chars from ALPHA / DIGIT / "-" / "." / "_" / "~"
65
- const pkceVerifierRegex = /^[A-Za-z0-9_.~-]{43,128}$/; // TODO: move to shared regex utils
65
+ const pkceVerifierRegex = /^[A-Za-z0-9_.~-]{43,128}$/;
66
66
  const authorizationCodeGrant = zod_1.z.object({
67
- grant_type: zod_1.z.literal("authorization_code"),
67
+ grant_type: zod_1.z.literal('authorization_code'),
68
68
  /** Authorization code returned from the /authorize step */
69
- code: zod_1.z.string().min(1, "code is required"),
69
+ code: zod_1.z.string().min(1, 'code is required'),
70
70
  /** Must exactly match the redirect URI used when obtaining the code */
71
71
  redirect_uri: zod_1.z.string().url(),
72
- /** Public client identifier; UUID in your example */
73
- client_id: zod_1.z.string().uuid(),
72
+ /** Public client identifier */
73
+ client_id: zod_1.z.string().min(1),
74
74
  /** PKCE verifier bound to the code */
75
- code_verifier: zod_1.z.string().regex(pkceVerifierRegex, "code_verifier must be 43–128 chars of A–Z, a–z, 0–9, '-', '.', '_' or '~'"),
76
- /** Optional resource/audience (used by some providers like AAD v1) */
77
- resource: zod_1.z.string().url().describe("FrontMcp scope url"),
75
+ code_verifier: zod_1.z
76
+ .string()
77
+ .regex(pkceVerifierRegex, "code_verifier must be 43–128 chars of A–Z, a–z, 0–9, '-', '.', '_' or '~'"),
78
+ });
79
+ const refreshTokenGrant = zod_1.z.object({
80
+ grant_type: zod_1.z.literal('refresh_token'),
81
+ /** The refresh token */
82
+ refresh_token: zod_1.z.string().min(1, 'refresh_token is required'),
83
+ /** Public client identifier */
84
+ client_id: zod_1.z.string().min(1),
78
85
  });
79
86
  const anonymousGrant = zod_1.z.object({
80
- grant_type: zod_1.z.literal("anonymous"),
81
- /** Public client identifier; UUID in your example */
82
- client_id: zod_1.z.string().uuid(),
87
+ grant_type: zod_1.z.literal('anonymous'),
88
+ /** Public client identifier */
89
+ client_id: zod_1.z.string().min(1),
83
90
  /** Target resource/audience is required for this custom flow */
84
- resource: zod_1.z.string().url(),
91
+ resource: zod_1.z.string().url().optional(),
85
92
  });
93
+ const tokenRequestSchema = zod_1.z.discriminatedUnion('grant_type', [
94
+ anonymousGrant,
95
+ authorizationCodeGrant,
96
+ refreshTokenGrant,
97
+ ]);
86
98
  const stateSchema = zod_1.z.object({
87
- body: zod_1.z.discriminatedUnion('grant_type', [anonymousGrant, authorizationCodeGrant]),
88
- isDefaultAuthProvider: zod_1.z.boolean().describe("If FrontMcp initialized without auth options"),
99
+ body: tokenRequestSchema.optional(),
100
+ grantType: zod_1.z.enum(['authorization_code', 'refresh_token', 'anonymous']).optional(),
101
+ isDefaultAuthProvider: zod_1.z.boolean().describe('If FrontMcp initialized without auth options'),
102
+ isOrchestrated: zod_1.z.boolean().describe('If auth mode is orchestrated'),
103
+ // Token response data
104
+ tokenResponse: zod_1.z
105
+ .object({
106
+ access_token: zod_1.z.string(),
107
+ token_type: zod_1.z.literal('Bearer'),
108
+ expires_in: zod_1.z.number(),
109
+ refresh_token: zod_1.z.string().optional(),
110
+ scope: zod_1.z.string().optional(),
111
+ })
112
+ .optional(),
113
+ // Error data
114
+ error: zod_1.z.string().optional(),
115
+ errorDescription: zod_1.z.string().optional(),
89
116
  });
90
117
  const outputSchema = common_1.HttpJsonSchema;
91
118
  const plan = {
92
- pre: [
93
- 'parseInput',
94
- 'validateInput',
95
- ],
96
- execute: [
97
- 'generateJWT',
98
- 'buildAuthorizeOutput'
99
- ],
100
- post: [
101
- 'validateOutput',
102
- ],
119
+ pre: ['parseInput', 'validateInput'],
120
+ execute: ['handleAuthorizationCodeGrant', 'handleRefreshTokenGrant', 'handleAnonymousGrant', 'buildTokenResponse'],
121
+ post: ['validateOutput'],
103
122
  };
104
123
  const name = 'oauth:token';
105
124
  const Stage = (0, common_1.StageHookOf)(name);
106
125
  let OauthTokenFlow = class OauthTokenFlow extends common_1.FlowBase {
126
+ logger = this.scope.logger.child('OauthTokenFlow');
107
127
  async parseInput() {
108
128
  const { metadata } = this.scope;
109
129
  const { request } = this.rawInput;
110
- if (!metadata.auth) {
111
- const isDefaultAuthProvider = true;
112
- this.state.set(stateSchema.parse({
113
- isDefaultAuthProvider, //
114
- body: request.body,
115
- }));
130
+ // Determine if we're using default (anonymous) auth or orchestrated
131
+ const isDefaultAuthProvider = !metadata.auth;
132
+ const isOrchestrated = !isDefaultAuthProvider;
133
+ try {
134
+ const body = tokenRequestSchema.parse(request.body);
135
+ this.state.set({
136
+ isDefaultAuthProvider,
137
+ isOrchestrated,
138
+ body,
139
+ grantType: body.grant_type,
140
+ });
116
141
  }
117
- else {
118
- // TODO:
119
- // support local/remote proxy auth provider
120
- // the call next only if scope isn't orchestrated
121
- this.next();
142
+ catch (err) {
143
+ this.logger.warn('Invalid token request body', err);
144
+ this.state.set({
145
+ isDefaultAuthProvider,
146
+ isOrchestrated,
147
+ error: 'invalid_request',
148
+ errorDescription: 'Invalid request body',
149
+ });
122
150
  }
123
151
  }
124
152
  async validateInput() {
153
+ const { error, errorDescription } = this.state;
154
+ if (error) {
155
+ this.respond(common_1.httpRespond.json({
156
+ error,
157
+ error_description: errorDescription,
158
+ }, { status: 400 }));
159
+ }
160
+ }
161
+ async handleAuthorizationCodeGrant() {
162
+ const { body, isDefaultAuthProvider } = this.state.required;
163
+ if (body?.grant_type !== 'authorization_code')
164
+ return;
165
+ // For default auth provider with "anonymous" code, just issue anonymous tokens
166
+ if (isDefaultAuthProvider && body.code === 'anonymous') {
167
+ const localAuth = this.scope.auth;
168
+ const accessToken = await localAuth.signAnonymousJwt();
169
+ this.state.set('tokenResponse', {
170
+ access_token: accessToken,
171
+ token_type: 'Bearer',
172
+ expires_in: 86400,
173
+ refresh_token: (0, crypto_1.randomUUID)(),
174
+ });
175
+ return;
176
+ }
177
+ // Real authorization code exchange
125
178
  const localAuth = this.scope.auth;
126
- const access_token = await localAuth.signAnonymousJwt();
127
- const refresh_token = (0, crypto_1.randomUUID)();
128
- this.respond(common_1.httpRespond.json({
129
- access_token,
179
+ const result = await localAuth.exchangeCode(body.code, body.client_id, body.redirect_uri, body.code_verifier);
180
+ if ('error' in result) {
181
+ this.logger.warn(`Code exchange failed: ${result.error}`);
182
+ this.respond(common_1.httpRespond.json({
183
+ error: result.error,
184
+ error_description: result.error_description,
185
+ }, { status: 400 }));
186
+ return;
187
+ }
188
+ this.state.set('tokenResponse', {
189
+ access_token: result.access_token,
190
+ token_type: result.token_type,
191
+ expires_in: result.expires_in,
192
+ refresh_token: result.refresh_token,
193
+ scope: result.scope,
194
+ });
195
+ }
196
+ async handleRefreshTokenGrant() {
197
+ const { body, isDefaultAuthProvider } = this.state.required;
198
+ if (body?.grant_type !== 'refresh_token')
199
+ return;
200
+ // For default auth provider, just issue new anonymous tokens
201
+ if (isDefaultAuthProvider) {
202
+ const localAuth = this.scope.auth;
203
+ const accessToken = await localAuth.signAnonymousJwt();
204
+ this.state.set('tokenResponse', {
205
+ access_token: accessToken,
206
+ token_type: 'Bearer',
207
+ expires_in: 86400,
208
+ refresh_token: (0, crypto_1.randomUUID)(),
209
+ });
210
+ return;
211
+ }
212
+ // Real refresh token exchange
213
+ const localAuth = this.scope.auth;
214
+ const result = await localAuth.refreshAccessToken(body.refresh_token, body.client_id);
215
+ if ('error' in result) {
216
+ this.logger.warn(`Refresh token failed: ${result.error}`);
217
+ this.respond(common_1.httpRespond.json({
218
+ error: result.error,
219
+ error_description: result.error_description,
220
+ }, { status: 400 }));
221
+ return;
222
+ }
223
+ this.state.set('tokenResponse', {
224
+ access_token: result.access_token,
225
+ token_type: result.token_type,
226
+ expires_in: result.expires_in,
227
+ refresh_token: result.refresh_token,
228
+ scope: result.scope,
229
+ });
230
+ }
231
+ async handleAnonymousGrant() {
232
+ const localAuth = this.scope.auth;
233
+ const accessToken = await localAuth.signAnonymousJwt();
234
+ this.state.set('tokenResponse', {
235
+ access_token: accessToken,
130
236
  token_type: 'Bearer',
131
- expires_in: 86500,
132
- refresh_token,
133
- }));
134
- // TBD
237
+ expires_in: 86400,
238
+ refresh_token: (0, crypto_1.randomUUID)(),
239
+ });
135
240
  }
136
- async buildAuthorizeOutput() {
137
- // TBD
241
+ async buildTokenResponse() {
242
+ const { tokenResponse } = this.state;
243
+ if (!tokenResponse) {
244
+ this.respond(common_1.httpRespond.json({
245
+ error: 'server_error',
246
+ error_description: 'Failed to generate tokens',
247
+ }, { status: 500 }));
248
+ return;
249
+ }
250
+ this.logger.info('Token response generated successfully');
251
+ this.respond(common_1.httpRespond.json(tokenResponse));
138
252
  }
139
253
  async validateOutput() {
140
- // TBD
254
+ // Schema handles output validation
141
255
  }
142
256
  };
143
257
  tslib_1.__decorate([
@@ -153,11 +267,35 @@ tslib_1.__decorate([
153
267
  tslib_1.__metadata("design:returntype", Promise)
154
268
  ], OauthTokenFlow.prototype, "validateInput", null);
155
269
  tslib_1.__decorate([
156
- Stage('buildAuthorizeOutput'),
270
+ Stage('handleAuthorizationCodeGrant', {
271
+ filter: ({ state }) => state.grantType === 'authorization_code',
272
+ }),
273
+ tslib_1.__metadata("design:type", Function),
274
+ tslib_1.__metadata("design:paramtypes", []),
275
+ tslib_1.__metadata("design:returntype", Promise)
276
+ ], OauthTokenFlow.prototype, "handleAuthorizationCodeGrant", null);
277
+ tslib_1.__decorate([
278
+ Stage('handleRefreshTokenGrant', {
279
+ filter: ({ state }) => state.grantType === 'refresh_token',
280
+ }),
281
+ tslib_1.__metadata("design:type", Function),
282
+ tslib_1.__metadata("design:paramtypes", []),
283
+ tslib_1.__metadata("design:returntype", Promise)
284
+ ], OauthTokenFlow.prototype, "handleRefreshTokenGrant", null);
285
+ tslib_1.__decorate([
286
+ Stage('handleAnonymousGrant', {
287
+ filter: ({ state }) => state.grantType === 'anonymous',
288
+ }),
289
+ tslib_1.__metadata("design:type", Function),
290
+ tslib_1.__metadata("design:paramtypes", []),
291
+ tslib_1.__metadata("design:returntype", Promise)
292
+ ], OauthTokenFlow.prototype, "handleAnonymousGrant", null);
293
+ tslib_1.__decorate([
294
+ Stage('buildTokenResponse'),
157
295
  tslib_1.__metadata("design:type", Function),
158
296
  tslib_1.__metadata("design:paramtypes", []),
159
297
  tslib_1.__metadata("design:returntype", Promise)
160
- ], OauthTokenFlow.prototype, "buildAuthorizeOutput", null);
298
+ ], OauthTokenFlow.prototype, "buildTokenResponse", null);
161
299
  tslib_1.__decorate([
162
300
  Stage('validateOutput'),
163
301
  tslib_1.__metadata("design:type", Function),
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.token.flow.js","sourceRoot":"","sources":["../../../../src/auth/flows/oauth.token.flow.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Token Endpoint — POST /oauth/token\n *\n * Who calls: Client (server-to-server).\n *\n * When: After getting the code (or for refresh).\n *\n * Purpose: Exchange authorization code + PKCE verifier for access token (and optional refresh token), or refresh an access token.\n */\n/**\n * Typical parameter shapes\n *\n * /oauth/token (POST, application/x-www-form-urlencoded)\n *\n * For code exchange: grant_type=authorization_code, code, redirect_uri, client_id (and auth), code_verifier\n *\n * For refresh: grant_type=refresh_token, refresh_token, client_id (and auth)\n */\n/**\n * Quick checklist (security & correctness)\n * - PKCE (S256) required for public clients (and basically for all).\n * - Use authorization code grant only (no implicit/hybrid).\n * - Rotate refresh tokens and bind them to client + user + scopes.\n * - Prefer private_key_jwt or mTLS for confidential clients.\n * - PAR + JAR recommended for higher security.\n * - Consider DPoP (proof-of-possession) to reduce token replay.\n * - Keep codes very short-lived (e.g., ≤60 s) and single-use.\n * - Publish discovery and JWKS, rotate keys safely.\n * - Decide JWT vs opaque access tokens; provide introspection if opaque.\n */\n\n/**\n *\n * OAuth 2.0 Device Authorization Grant (“device code flow”)\n * Who does what (at a glance)\n *\n * Device/TV/CLI (no browser)\n * Calls POST /oauth/device_authorization, shows the user a code + URL, and polls POST /oauth/token.\n *\n * User (on phone/laptop browser)\n * Visits the given verification_uri and authenticates using your normal OAuth login (whatever you already have). No new UI required beyond two tiny endpoints.\n *\n * Auth Server (you)\n * Stores the device transaction and, after the user authenticates, marks it as approved so the device’s /oauth/token polling succeeds.\n *\n * Endpoints you need (only two “new” ones)\n *\n * POST /oauth/device_authorization ✅ (device calls)\n *\n * POST /oauth/token with grant urn:ietf:params:oauth:grant-type:device_code ✅ (device polls)\n *\n * GET /activate ➜ “UI handler” (user lands here from verification_uri — this just redirects into your existing /oauth/authorize)\n *\n * GET /activate/callback ➜ “UI handler” (your existing flow returns here after the user logs in; you flip the device record to approved and show a basic “All set” page)\n *\n * That’s it. No pages with complex consent screens are required; reuse your normal /oauth/authorize\n */\n\nimport {\n Flow, FlowBase, FlowPlan,\n FlowRunOptions,\n httpInputSchema, HttpJsonSchema,\n httpRespond,\n StageHookOf\n} from \"../../common\";\nimport {z} from \"zod\";\nimport {randomUUID} from \"crypto\";\nimport {LocalPrimaryAuth} from \"../instances/instance.local-primary-auth\";\n\n\nconst inputSchema = httpInputSchema;\n\n// RFC 7636 PKCE: code_verifier is 43–128 chars from ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\nconst pkceVerifierRegex = /^[A-Za-z0-9_.~-]{43,128}$/; // TODO: move to shared regex utils\nconst authorizationCodeGrant = z.object({\n grant_type: z.literal(\"authorization_code\"),\n /** Authorization code returned from the /authorize step */\n code: z.string().min(1, \"code is required\"),\n /** Must exactly match the redirect URI used when obtaining the code */\n redirect_uri: z.string().url(),\n /** Public client identifier; UUID in your example */\n client_id: z.string().uuid(),\n /** PKCE verifier bound to the code */\n code_verifier: z.string().regex(pkceVerifierRegex, \"code_verifier must be 43–128 chars of A–Z, a–z, 0–9, '-', '.', '_' or '~'\",),\n /** Optional resource/audience (used by some providers like AAD v1) */\n resource: z.string().url().describe(\"FrontMcp scope url\"),\n});\nconst anonymousGrant = z.object({\n grant_type: z.literal(\"anonymous\"),\n /** Public client identifier; UUID in your example */\n client_id: z.string().uuid(),\n /** Target resource/audience is required for this custom flow */\n resource: z.string().url(),\n});\n\nconst stateSchema = z.object({\n body: z.discriminatedUnion('grant_type', [anonymousGrant, authorizationCodeGrant]),\n isDefaultAuthProvider: z.boolean().describe(\"If FrontMcp initialized without auth options\"),\n});\n\nconst outputSchema = HttpJsonSchema;\n\n\nconst plan = {\n pre: [\n 'parseInput',\n 'validateInput',\n ],\n execute: [\n 'generateJWT',\n 'buildAuthorizeOutput'\n ],\n post: [\n 'validateOutput',\n ],\n} as const satisfies FlowPlan<string>;\n\ndeclare global {\n interface ExtendFlows {\n 'oauth:token': FlowRunOptions<\n OauthTokenFlow,\n typeof plan,\n typeof inputSchema,\n typeof outputSchema,\n typeof stateSchema\n >;\n }\n}\n\nconst name = 'oauth:token' as const;\nconst Stage = StageHookOf(name);\n\n@Flow({\n name,\n plan,\n inputSchema,\n outputSchema,\n access: 'public',\n middleware: {\n method: 'POST',\n path: '/oauth/token',\n },\n})\nexport default class OauthTokenFlow extends FlowBase<typeof name> {\n\n @Stage('parseInput')\n async parseInput() {\n const {metadata} = this.scope;\n const {request} = this.rawInput;\n\n\n if (!metadata.auth) {\n const isDefaultAuthProvider = true\n this.state.set(stateSchema.parse({\n isDefaultAuthProvider, //\n body: request.body,\n }))\n } else {\n // TODO:\n // support local/remote proxy auth provider\n // the call next only if scope isn't orchestrated\n this.next()\n }\n }\n\n @Stage('validateInput')\n async validateInput() {\n\n const localAuth = this.scope.auth as LocalPrimaryAuth;\n const access_token = await localAuth.signAnonymousJwt()\n const refresh_token = randomUUID()\n this.respond(httpRespond.json({\n access_token,\n token_type: 'Bearer',\n expires_in: 86500,\n refresh_token,\n }))\n\n // TBD\n }\n\n\n @Stage('buildAuthorizeOutput')\n async buildAuthorizeOutput() {\n // TBD\n }\n\n @Stage('validateOutput')\n async validateOutput() {\n // TBD\n }\n}"]}
1
+ {"version":3,"file":"oauth.token.flow.js","sourceRoot":"","sources":["../../../../src/auth/flows/oauth.token.flow.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Token Endpoint — POST /oauth/token\n *\n * Who calls: Client (server-to-server).\n *\n * When: After getting the code (or for refresh).\n *\n * Purpose: Exchange authorization code + PKCE verifier for access token (and optional refresh token), or refresh an access token.\n */\n/**\n * Typical parameter shapes\n *\n * /oauth/token (POST, application/x-www-form-urlencoded)\n *\n * For code exchange: grant_type=authorization_code, code, redirect_uri, client_id (and auth), code_verifier\n *\n * For refresh: grant_type=refresh_token, refresh_token, client_id (and auth)\n */\n/**\n * Quick checklist (security & correctness)\n * - PKCE (S256) required for public clients (and basically for all).\n * - Use authorization code grant only (no implicit/hybrid).\n * - Rotate refresh tokens and bind them to client + user + scopes.\n * - Prefer private_key_jwt or mTLS for confidential clients.\n * - PAR + JAR recommended for higher security.\n * - Consider DPoP (proof-of-possession) to reduce token replay.\n * - Keep codes very short-lived (e.g., ≤60 s) and single-use.\n * - Publish discovery and JWKS, rotate keys safely.\n * - Decide JWT vs opaque access tokens; provide introspection if opaque.\n */\n\n/**\n *\n * OAuth 2.0 Device Authorization Grant (\"device code flow\")\n * Who does what (at a glance)\n *\n * Device/TV/CLI (no browser)\n * Calls POST /oauth/device_authorization, shows the user a code + URL, and polls POST /oauth/token.\n *\n * User (on phone/laptop browser)\n * Visits the given verification_uri and authenticates using your normal OAuth login (whatever you already have). No new UI required beyond two tiny endpoints.\n *\n * Auth Server (you)\n * Stores the device transaction and, after the user authenticates, marks it as approved so the device's /oauth/token polling succeeds.\n *\n * Endpoints you need (only two \"new\" ones)\n *\n * POST /oauth/device_authorization ✅ (device calls)\n *\n * POST /oauth/token with grant urn:ietf:params:oauth:grant-type:device_code ✅ (device polls)\n *\n * GET /activate ➜ \"UI handler\" (user lands here from verification_uri — this just redirects into your existing /oauth/authorize)\n *\n * GET /activate/callback ➜ \"UI handler\" (your existing flow returns here after the user logs in; you flip the device record to approved and show a basic \"All set\" page)\n *\n * That's it. No pages with complex consent screens are required; reuse your normal /oauth/authorize\n */\n\nimport {\n Flow,\n FlowBase,\n FlowPlan,\n FlowRunOptions,\n httpInputSchema,\n HttpJsonSchema,\n httpRespond,\n StageHookOf,\n} from '../../common';\nimport { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { LocalPrimaryAuth, TokenResponse } from '../instances/instance.local-primary-auth';\n\nconst inputSchema = httpInputSchema;\n\n// RFC 7636 PKCE: code_verifier is 43–128 chars from ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\nconst pkceVerifierRegex = /^[A-Za-z0-9_.~-]{43,128}$/;\n\nconst authorizationCodeGrant = z.object({\n grant_type: z.literal('authorization_code'),\n /** Authorization code returned from the /authorize step */\n code: z.string().min(1, 'code is required'),\n /** Must exactly match the redirect URI used when obtaining the code */\n redirect_uri: z.string().url(),\n /** Public client identifier */\n client_id: z.string().min(1),\n /** PKCE verifier bound to the code */\n code_verifier: z\n .string()\n .regex(pkceVerifierRegex, \"code_verifier must be 43–128 chars of A–Z, a–z, 0–9, '-', '.', '_' or '~'\"),\n});\n\nconst refreshTokenGrant = z.object({\n grant_type: z.literal('refresh_token'),\n /** The refresh token */\n refresh_token: z.string().min(1, 'refresh_token is required'),\n /** Public client identifier */\n client_id: z.string().min(1),\n});\n\nconst anonymousGrant = z.object({\n grant_type: z.literal('anonymous'),\n /** Public client identifier */\n client_id: z.string().min(1),\n /** Target resource/audience is required for this custom flow */\n resource: z.string().url().optional(),\n});\n\nconst tokenRequestSchema = z.discriminatedUnion('grant_type', [\n anonymousGrant,\n authorizationCodeGrant,\n refreshTokenGrant,\n]);\n\ntype TokenRequest = z.infer<typeof tokenRequestSchema>;\n\nconst stateSchema = z.object({\n body: tokenRequestSchema.optional(),\n grantType: z.enum(['authorization_code', 'refresh_token', 'anonymous']).optional(),\n isDefaultAuthProvider: z.boolean().describe('If FrontMcp initialized without auth options'),\n isOrchestrated: z.boolean().describe('If auth mode is orchestrated'),\n // Token response data\n tokenResponse: z\n .object({\n access_token: z.string(),\n token_type: z.literal('Bearer'),\n expires_in: z.number(),\n refresh_token: z.string().optional(),\n scope: z.string().optional(),\n })\n .optional(),\n // Error data\n error: z.string().optional(),\n errorDescription: z.string().optional(),\n});\n\nconst outputSchema = HttpJsonSchema;\n\nconst plan = {\n pre: ['parseInput', 'validateInput'],\n execute: ['handleAuthorizationCodeGrant', 'handleRefreshTokenGrant', 'handleAnonymousGrant', 'buildTokenResponse'],\n post: ['validateOutput'],\n} as const satisfies FlowPlan<string>;\n\ndeclare global {\n interface ExtendFlows {\n 'oauth:token': FlowRunOptions<\n OauthTokenFlow,\n typeof plan,\n typeof inputSchema,\n typeof outputSchema,\n typeof stateSchema\n >;\n }\n}\n\nconst name = 'oauth:token' as const;\nconst Stage = StageHookOf(name);\n\n@Flow({\n name,\n plan,\n inputSchema,\n outputSchema,\n access: 'public',\n middleware: {\n method: 'POST',\n path: '/oauth/token',\n },\n})\nexport default class OauthTokenFlow extends FlowBase<typeof name> {\n private logger = this.scope.logger.child('OauthTokenFlow');\n\n @Stage('parseInput')\n async parseInput() {\n const { metadata } = this.scope;\n const { request } = this.rawInput;\n\n // Determine if we're using default (anonymous) auth or orchestrated\n const isDefaultAuthProvider = !metadata.auth;\n const isOrchestrated = !isDefaultAuthProvider;\n\n try {\n const body = tokenRequestSchema.parse(request.body);\n this.state.set({\n isDefaultAuthProvider,\n isOrchestrated,\n body,\n grantType: body.grant_type,\n });\n } catch (err) {\n this.logger.warn('Invalid token request body', err);\n this.state.set({\n isDefaultAuthProvider,\n isOrchestrated,\n error: 'invalid_request',\n errorDescription: 'Invalid request body',\n });\n }\n }\n\n @Stage('validateInput')\n async validateInput() {\n const { error, errorDescription } = this.state;\n\n if (error) {\n this.respond(\n httpRespond.json(\n {\n error,\n error_description: errorDescription,\n },\n { status: 400 },\n ),\n );\n }\n }\n\n @Stage('handleAuthorizationCodeGrant', {\n filter: ({ state }) => state.grantType === 'authorization_code',\n })\n async handleAuthorizationCodeGrant() {\n const { body, isDefaultAuthProvider } = this.state.required;\n\n if (body?.grant_type !== 'authorization_code') return;\n\n // For default auth provider with \"anonymous\" code, just issue anonymous tokens\n if (isDefaultAuthProvider && body.code === 'anonymous') {\n const localAuth = this.scope.auth as LocalPrimaryAuth;\n const accessToken = await localAuth.signAnonymousJwt();\n\n this.state.set('tokenResponse', {\n access_token: accessToken,\n token_type: 'Bearer',\n expires_in: 86400,\n refresh_token: randomUUID(),\n });\n return;\n }\n\n // Real authorization code exchange\n const localAuth = this.scope.auth as LocalPrimaryAuth;\n const result = await localAuth.exchangeCode(body.code, body.client_id, body.redirect_uri, body.code_verifier);\n\n if ('error' in result) {\n this.logger.warn(`Code exchange failed: ${result.error}`);\n this.respond(\n httpRespond.json(\n {\n error: result.error,\n error_description: result.error_description,\n },\n { status: 400 },\n ),\n );\n return;\n }\n\n this.state.set('tokenResponse', {\n access_token: result.access_token,\n token_type: result.token_type,\n expires_in: result.expires_in,\n refresh_token: result.refresh_token,\n scope: result.scope,\n });\n }\n\n @Stage('handleRefreshTokenGrant', {\n filter: ({ state }) => state.grantType === 'refresh_token',\n })\n async handleRefreshTokenGrant() {\n const { body, isDefaultAuthProvider } = this.state.required;\n\n if (body?.grant_type !== 'refresh_token') return;\n\n // For default auth provider, just issue new anonymous tokens\n if (isDefaultAuthProvider) {\n const localAuth = this.scope.auth as LocalPrimaryAuth;\n const accessToken = await localAuth.signAnonymousJwt();\n\n this.state.set('tokenResponse', {\n access_token: accessToken,\n token_type: 'Bearer',\n expires_in: 86400,\n refresh_token: randomUUID(),\n });\n return;\n }\n\n // Real refresh token exchange\n const localAuth = this.scope.auth as LocalPrimaryAuth;\n const result = await localAuth.refreshAccessToken(body.refresh_token, body.client_id);\n\n if ('error' in result) {\n this.logger.warn(`Refresh token failed: ${result.error}`);\n this.respond(\n httpRespond.json(\n {\n error: result.error,\n error_description: result.error_description,\n },\n { status: 400 },\n ),\n );\n return;\n }\n\n this.state.set('tokenResponse', {\n access_token: result.access_token,\n token_type: result.token_type,\n expires_in: result.expires_in,\n refresh_token: result.refresh_token,\n scope: result.scope,\n });\n }\n\n @Stage('handleAnonymousGrant', {\n filter: ({ state }) => state.grantType === 'anonymous',\n })\n async handleAnonymousGrant() {\n const localAuth = this.scope.auth as LocalPrimaryAuth;\n const accessToken = await localAuth.signAnonymousJwt();\n\n this.state.set('tokenResponse', {\n access_token: accessToken,\n token_type: 'Bearer',\n expires_in: 86400,\n refresh_token: randomUUID(),\n });\n }\n\n @Stage('buildTokenResponse')\n async buildTokenResponse() {\n const { tokenResponse } = this.state;\n\n if (!tokenResponse) {\n this.respond(\n httpRespond.json(\n {\n error: 'server_error',\n error_description: 'Failed to generate tokens',\n },\n { status: 500 },\n ),\n );\n return;\n }\n\n this.logger.info('Token response generated successfully');\n this.respond(httpRespond.json(tokenResponse));\n }\n\n @Stage('validateOutput')\n async validateOutput() {\n // Schema handles output validation\n }\n}\n"]}