@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.
- package/README.md +30 -18
- package/package.json +20 -5
- package/src/app/app.registry.d.ts +3 -2
- package/src/app/app.registry.js +3 -1
- package/src/app/app.registry.js.map +1 -1
- package/src/app/instances/app.local.instance.js +2 -2
- package/src/app/instances/app.local.instance.js.map +1 -1
- package/src/auth/auth.registry.d.ts +34 -2
- package/src/auth/auth.registry.js +162 -24
- package/src/auth/auth.registry.js.map +1 -1
- package/src/auth/auth.utils.js +8 -9
- package/src/auth/auth.utils.js.map +1 -1
- package/src/auth/authorization/authorization.class.d.ts +125 -0
- package/src/auth/authorization/authorization.class.js +224 -0
- package/src/auth/authorization/authorization.class.js.map +1 -0
- package/src/auth/authorization/authorization.types.d.ts +300 -0
- package/src/auth/authorization/authorization.types.js +79 -0
- package/src/auth/authorization/authorization.types.js.map +1 -0
- package/src/auth/authorization/index.d.ts +5 -0
- package/src/auth/authorization/index.js +19 -0
- package/src/auth/authorization/index.js.map +1 -0
- package/src/auth/authorization/orchestrated.authorization.d.ts +242 -0
- package/src/auth/authorization/orchestrated.authorization.js +306 -0
- package/src/auth/authorization/orchestrated.authorization.js.map +1 -0
- package/src/auth/authorization/public.authorization.d.ts +91 -0
- package/src/auth/authorization/public.authorization.js +132 -0
- package/src/auth/authorization/public.authorization.js.map +1 -0
- package/src/auth/authorization/transparent.authorization.d.ts +130 -0
- package/src/auth/authorization/transparent.authorization.js +147 -0
- package/src/auth/authorization/transparent.authorization.js.map +1 -0
- package/src/auth/consent/consent.types.d.ts +111 -0
- package/src/auth/consent/consent.types.js +119 -0
- package/src/auth/consent/consent.types.js.map +1 -0
- package/src/auth/consent/index.d.ts +1 -0
- package/src/auth/consent/index.js +13 -0
- package/src/auth/consent/index.js.map +1 -0
- package/src/auth/detection/auth-provider-detection.d.ts +84 -0
- package/src/auth/detection/auth-provider-detection.js +230 -0
- package/src/auth/detection/auth-provider-detection.js.map +1 -0
- package/src/auth/detection/index.d.ts +1 -0
- package/src/auth/detection/index.js +15 -0
- package/src/auth/detection/index.js.map +1 -0
- package/src/auth/flows/auth.verify.flow.d.ts +110 -0
- package/src/auth/flows/auth.verify.flow.js +379 -0
- package/src/auth/flows/auth.verify.flow.js.map +1 -0
- package/src/auth/flows/oauth.authorize.flow.d.ts +118 -164
- package/src/auth/flows/oauth.authorize.flow.js +701 -33
- package/src/auth/flows/oauth.authorize.flow.js.map +1 -1
- package/src/auth/flows/oauth.callback.flow.d.ts +117 -0
- package/src/auth/flows/oauth.callback.flow.js +357 -0
- package/src/auth/flows/oauth.callback.flow.js.map +1 -0
- package/src/auth/flows/oauth.register.flow.d.ts +32 -125
- package/src/auth/flows/oauth.token.flow.d.ts +52 -154
- package/src/auth/flows/oauth.token.flow.js +193 -55
- package/src/auth/flows/oauth.token.flow.js.map +1 -1
- package/src/auth/flows/session.verify.flow.d.ts +66 -321
- package/src/auth/flows/session.verify.flow.js +107 -18
- package/src/auth/flows/session.verify.flow.js.map +1 -1
- package/src/auth/flows/well-known.jwks.flow.d.ts +34 -205
- package/src/auth/flows/well-known.jwks.flow.js +15 -8
- package/src/auth/flows/well-known.jwks.flow.js.map +1 -1
- package/src/auth/flows/well-known.oauth-authorization-server.flow.d.ts +48 -223
- package/src/auth/flows/well-known.oauth-authorization-server.flow.js +2 -3
- package/src/auth/flows/well-known.oauth-authorization-server.flow.js.map +1 -1
- package/src/auth/flows/well-known.prm.flow.d.ts +19 -120
- package/src/auth/flows/well-known.prm.flow.js +3 -4
- package/src/auth/flows/well-known.prm.flow.js.map +1 -1
- package/src/auth/instances/instance.local-primary-auth.d.ts +91 -4
- package/src/auth/instances/instance.local-primary-auth.js +236 -6
- package/src/auth/instances/instance.local-primary-auth.js.map +1 -1
- package/src/auth/instances/instance.remote-primary-auth.d.ts +4 -3
- package/src/auth/instances/instance.remote-primary-auth.js +2 -2
- package/src/auth/instances/instance.remote-primary-auth.js.map +1 -1
- package/src/auth/session/authorization-vault.d.ts +611 -0
- package/src/auth/session/authorization-vault.js +817 -0
- package/src/auth/session/authorization-vault.js.map +1 -0
- package/src/auth/session/authorization.store.d.ts +301 -0
- package/src/auth/session/authorization.store.js +323 -0
- package/src/auth/session/authorization.store.js.map +1 -0
- package/src/auth/session/encrypted-authorization-vault.d.ts +181 -0
- package/src/auth/session/encrypted-authorization-vault.js +493 -0
- package/src/auth/session/encrypted-authorization-vault.js.map +1 -0
- package/src/auth/session/index.d.ts +4 -4
- package/src/auth/session/index.js +11 -7
- package/src/auth/session/index.js.map +1 -1
- package/src/auth/session/session.schema.d.ts +1 -1
- package/src/auth/session/session.service.d.ts +1 -1
- package/src/auth/session/transport-session.manager.d.ts +101 -0
- package/src/auth/session/transport-session.manager.js +300 -0
- package/src/auth/session/transport-session.manager.js.map +1 -0
- package/src/auth/session/transport-session.types.d.ts +457 -0
- package/src/auth/session/transport-session.types.js +110 -0
- package/src/auth/session/transport-session.types.js.map +1 -0
- package/src/auth/session/utils/session-id.utils.d.ts +14 -2
- package/src/auth/session/utils/session-id.utils.js +68 -19
- package/src/auth/session/utils/session-id.utils.js.map +1 -1
- package/src/auth/session/vault-encryption.d.ts +189 -0
- package/src/auth/session/vault-encryption.js +263 -0
- package/src/auth/session/vault-encryption.js.map +1 -0
- package/src/auth/ui/base-layout.d.ts +188 -0
- package/src/auth/ui/base-layout.js +292 -0
- package/src/auth/ui/base-layout.js.map +1 -0
- package/src/auth/ui/htmx-templates.d.ts +135 -0
- package/src/auth/ui/htmx-templates.js +433 -0
- package/src/auth/ui/htmx-templates.js.map +1 -0
- package/src/auth/ui/index.d.ts +11 -0
- package/src/auth/ui/index.js +35 -0
- package/src/auth/ui/index.js.map +1 -0
- package/src/auth/utils/audience.validator.d.ts +129 -0
- package/src/auth/utils/audience.validator.js +196 -0
- package/src/auth/utils/audience.validator.js.map +1 -0
- package/src/auth/utils/index.d.ts +2 -0
- package/src/auth/utils/index.js +7 -0
- package/src/auth/utils/index.js.map +1 -0
- package/src/auth/utils/www-authenticate.utils.d.ts +97 -0
- package/src/auth/utils/www-authenticate.utils.js +183 -0
- package/src/auth/utils/www-authenticate.utils.js.map +1 -0
- package/src/common/common.schema.d.ts +2 -16
- package/src/common/constants.d.ts +3 -0
- package/src/common/constants.js +6 -1
- package/src/common/constants.js.map +1 -1
- package/src/common/decorators/decorator-utils.d.ts +131 -0
- package/src/common/decorators/decorator-utils.js +195 -0
- package/src/common/decorators/decorator-utils.js.map +1 -0
- package/src/common/decorators/front-mcp.decorator.js +3 -2
- package/src/common/decorators/front-mcp.decorator.js.map +1 -1
- package/src/common/decorators/hook.decorator.d.ts +58 -2
- package/src/common/decorators/hook.decorator.js +127 -17
- package/src/common/decorators/hook.decorator.js.map +1 -1
- package/src/common/decorators/plugin.decorator.d.ts +1 -1
- package/src/common/decorators/plugin.decorator.js +11 -10
- package/src/common/decorators/plugin.decorator.js.map +1 -1
- package/src/common/decorators/resource.decorator.d.ts +32 -3
- package/src/common/decorators/resource.decorator.js +46 -4
- package/src/common/decorators/resource.decorator.js.map +1 -1
- package/src/common/decorators/tool.decorator.d.ts +54 -5
- package/src/common/decorators/tool.decorator.js.map +1 -1
- package/src/common/dynamic/dynamic.plugin.d.ts +22 -11
- package/src/common/dynamic/dynamic.plugin.js +7 -1
- package/src/common/dynamic/dynamic.plugin.js.map +1 -1
- package/src/common/entries/prompt.entry.d.ts +46 -2
- package/src/common/entries/prompt.entry.js +10 -0
- package/src/common/entries/prompt.entry.js.map +1 -1
- package/src/common/entries/resource.entry.d.ts +69 -6
- package/src/common/entries/resource.entry.js +27 -3
- package/src/common/entries/resource.entry.js.map +1 -1
- package/src/common/entries/scope.entry.d.ts +5 -1
- package/src/common/entries/scope.entry.js +3 -3
- package/src/common/entries/scope.entry.js.map +1 -1
- package/src/common/flow/flow.utils.d.ts +56 -0
- package/src/common/flow/flow.utils.js +96 -0
- package/src/common/flow/flow.utils.js.map +1 -0
- package/src/common/index.d.ts +2 -2
- package/src/common/index.js +2 -2
- package/src/common/index.js.map +1 -1
- package/src/common/interfaces/execution-context.interface.d.ts +59 -0
- package/src/common/interfaces/execution-context.interface.js +81 -0
- package/src/common/interfaces/execution-context.interface.js.map +1 -0
- package/src/common/interfaces/flow.interface.d.ts +1 -1
- package/src/common/interfaces/flow.interface.js.map +1 -1
- package/src/common/interfaces/index.d.ts +1 -0
- package/src/common/interfaces/index.js +1 -0
- package/src/common/interfaces/index.js.map +1 -1
- package/src/common/interfaces/internal/primary-auth-provider.interface.d.ts +17 -2
- package/src/common/interfaces/internal/primary-auth-provider.interface.js +52 -4
- package/src/common/interfaces/internal/primary-auth-provider.interface.js.map +1 -1
- package/src/common/interfaces/internal/registry.interface.d.ts +16 -2
- package/src/common/interfaces/internal/registry.interface.js.map +1 -1
- package/src/common/interfaces/plugin.interface.js.map +1 -1
- package/src/common/interfaces/prompt.interface.d.ts +53 -4
- package/src/common/interfaces/prompt.interface.js +78 -0
- package/src/common/interfaces/prompt.interface.js.map +1 -1
- package/src/common/interfaces/resource.interface.d.ts +47 -17
- package/src/common/interfaces/resource.interface.js +53 -0
- package/src/common/interfaces/resource.interface.js.map +1 -1
- package/src/common/interfaces/tool.interface.d.ts +39 -22
- package/src/common/interfaces/tool.interface.js +61 -34
- package/src/common/interfaces/tool.interface.js.map +1 -1
- package/src/common/metadata/adapter.metadata.d.ts +1 -9
- package/src/common/metadata/app.metadata.d.ts +425 -730
- package/src/common/metadata/auth-provider.metadata.d.ts +2 -12
- package/src/common/metadata/flow.metadata.d.ts +10 -25
- package/src/common/metadata/front-mcp.metadata.d.ts +602 -1023
- package/src/common/metadata/front-mcp.metadata.js +6 -4
- package/src/common/metadata/front-mcp.metadata.js.map +1 -1
- package/src/common/metadata/hook.metadata.d.ts +1 -1
- package/src/common/metadata/hook.metadata.js.map +1 -1
- package/src/common/metadata/index.d.ts +1 -0
- package/src/common/metadata/index.js +1 -0
- package/src/common/metadata/index.js.map +1 -1
- package/src/common/metadata/logger.metadata.d.ts +1 -9
- package/src/common/metadata/plugin.metadata.d.ts +8 -30
- package/src/common/metadata/prompt.metadata.d.ts +4 -161
- package/src/common/metadata/provider.metadata.d.ts +2 -12
- package/src/common/metadata/resource.metadata.d.ts +6 -98
- package/src/common/metadata/resource.metadata.js +15 -6
- package/src/common/metadata/resource.metadata.js.map +1 -1
- package/src/common/metadata/tool-ui.metadata.d.ts +10 -0
- package/src/common/metadata/tool-ui.metadata.js +12 -0
- package/src/common/metadata/tool-ui.metadata.js.map +1 -0
- package/src/common/metadata/tool.metadata.d.ts +78 -199
- package/src/common/metadata/tool.metadata.js +11 -14
- package/src/common/metadata/tool.metadata.js.map +1 -1
- package/src/common/providers/base-config.provider.d.ts +84 -0
- package/src/common/providers/base-config.provider.js +128 -0
- package/src/common/providers/base-config.provider.js.map +1 -0
- package/src/common/records/plugin.record.d.ts +5 -6
- package/src/common/records/plugin.record.js.map +1 -1
- package/src/common/records/prompt.record.js.map +1 -1
- package/src/common/records/resource.record.d.ts +17 -1
- package/src/common/records/resource.record.js +12 -6
- package/src/common/records/resource.record.js.map +1 -1
- package/src/common/records/tool.record.js.map +1 -1
- package/src/common/schemas/annotated-class.schema.d.ts +9 -9
- package/src/common/schemas/annotated-class.schema.js +92 -27
- package/src/common/schemas/annotated-class.schema.js.map +1 -1
- package/src/common/schemas/http-input.schema.d.ts +6 -30
- package/src/common/schemas/http-output.schema.d.ts +326 -1630
- package/src/common/schemas/http-output.schema.js +39 -1
- package/src/common/schemas/http-output.schema.js.map +1 -1
- package/src/common/tokens/front-mcp.tokens.js +4 -1
- package/src/common/tokens/front-mcp.tokens.js.map +1 -1
- package/src/common/tokens/resource.tokens.d.ts +2 -0
- package/src/common/tokens/resource.tokens.js +4 -1
- package/src/common/tokens/resource.tokens.js.map +1 -1
- package/src/common/tokens/tool.tokens.d.ts +2 -0
- package/src/common/tokens/tool.tokens.js +2 -0
- package/src/common/tokens/tool.tokens.js.map +1 -1
- package/src/common/types/auth/jwt.types.d.ts +5 -31
- package/src/common/types/auth/session.types.d.ts +97 -192
- package/src/common/types/auth/session.types.js +24 -11
- package/src/common/types/auth/session.types.js.map +1 -1
- package/src/common/types/options/auth.options.d.ts +1013 -490
- package/src/common/types/options/auth.options.js +554 -36
- package/src/common/types/options/auth.options.js.map +1 -1
- package/src/common/types/options/http.options.d.ts +1 -9
- package/src/common/types/options/logging.options.d.ts +7 -13
- package/src/common/types/options/logging.options.js +4 -0
- package/src/common/types/options/logging.options.js.map +1 -1
- package/src/common/types/options/server-info.options.d.ts +3 -31
- package/src/common/types/options/session.options.d.ts +90 -10
- package/src/common/types/options/session.options.js +26 -3
- package/src/common/types/options/session.options.js.map +1 -1
- package/src/common/utils/decide-request-intent.utils.d.ts +8 -46
- package/src/common/utils/decide-request-intent.utils.js +88 -23
- package/src/common/utils/decide-request-intent.utils.js.map +1 -1
- package/src/completion/flows/complete.flow.d.ts +74 -0
- package/src/completion/flows/complete.flow.js +199 -0
- package/src/completion/flows/complete.flow.js.map +1 -0
- package/src/errors/authorization-required.error.d.ts +189 -0
- package/src/errors/authorization-required.error.js +274 -0
- package/src/errors/authorization-required.error.js.map +1 -0
- package/src/errors/index.d.ts +2 -1
- package/src/errors/index.js +17 -1
- package/src/errors/index.js.map +1 -1
- package/src/errors/mcp.error.d.ts +101 -1
- package/src/errors/mcp.error.js +147 -2
- package/src/errors/mcp.error.js.map +1 -1
- package/src/flows/flow.instance.js +4 -3
- package/src/flows/flow.instance.js.map +1 -1
- package/src/flows/flow.registry.js.map +1 -1
- package/src/flows/flow.stages.js +14 -11
- package/src/flows/flow.stages.js.map +1 -1
- package/src/front-mcp/front-mcp.providers.d.ts +464 -102
- package/src/front-mcp/front-mcp.providers.js +3 -5
- package/src/front-mcp/front-mcp.providers.js.map +1 -1
- package/src/hooks/hook.instance.d.ts +1 -1
- package/src/hooks/hook.instance.js +5 -2
- package/src/hooks/hook.instance.js.map +1 -1
- package/src/hooks/hook.registry.js +7 -5
- package/src/hooks/hook.registry.js.map +1 -1
- package/src/index.d.ts +28 -9
- package/src/index.js +5 -1
- package/src/index.js.map +1 -1
- package/src/logger/instances/instance.logger.js +3 -2
- package/src/logger/instances/instance.logger.js.map +1 -1
- package/src/logger/logger.registry.js +7 -2
- package/src/logger/logger.registry.js.map +1 -1
- package/src/logging/flows/set-level.flow.d.ts +62 -0
- package/src/logging/flows/set-level.flow.js +108 -0
- package/src/logging/flows/set-level.flow.js.map +1 -0
- package/src/mcp-apps/csp.d.ts +111 -0
- package/src/mcp-apps/csp.js +267 -0
- package/src/mcp-apps/csp.js.map +1 -0
- package/src/mcp-apps/index.d.ts +23 -0
- package/src/mcp-apps/index.js +91 -0
- package/src/mcp-apps/index.js.map +1 -0
- package/src/mcp-apps/schemas.d.ts +403 -0
- package/src/mcp-apps/schemas.js +345 -0
- package/src/mcp-apps/schemas.js.map +1 -0
- package/src/mcp-apps/template.d.ts +94 -0
- package/src/mcp-apps/template.js +419 -0
- package/src/mcp-apps/template.js.map +1 -0
- package/src/mcp-apps/types.d.ts +323 -0
- package/src/mcp-apps/types.js +59 -0
- package/src/mcp-apps/types.js.map +1 -0
- package/src/notification/index.d.ts +1 -0
- package/src/notification/index.js +13 -0
- package/src/notification/index.js.map +1 -0
- package/src/notification/notification.service.d.ts +378 -0
- package/src/notification/notification.service.js +727 -0
- package/src/notification/notification.service.js.map +1 -0
- package/src/plugin/plugin.registry.js +12 -9
- package/src/plugin/plugin.registry.js.map +1 -1
- package/src/prompt/flows/get-prompt.flow.d.ts +153 -0
- package/src/prompt/flows/get-prompt.flow.js +214 -0
- package/src/prompt/flows/get-prompt.flow.js.map +1 -0
- package/src/prompt/flows/prompts-list.flow.d.ts +67 -0
- package/src/prompt/flows/prompts-list.flow.js +176 -0
- package/src/prompt/flows/prompts-list.flow.js.map +1 -0
- package/src/prompt/index.d.ts +7 -0
- package/src/prompt/index.js +17 -0
- package/src/prompt/index.js.map +1 -0
- package/src/prompt/prompt.events.d.ts +17 -0
- package/src/prompt/prompt.events.js +25 -0
- package/src/prompt/prompt.events.js.map +1 -0
- package/src/prompt/prompt.instance.d.ts +30 -0
- package/src/prompt/prompt.instance.js +120 -0
- package/src/prompt/prompt.instance.js.map +1 -0
- package/src/prompt/prompt.registry.d.ts +79 -12
- package/src/prompt/prompt.registry.js +360 -15
- package/src/prompt/prompt.registry.js.map +1 -1
- package/src/prompt/prompt.types.d.ts +26 -0
- package/src/prompt/prompt.types.js +11 -0
- package/src/prompt/prompt.types.js.map +1 -0
- package/src/prompt/prompt.utils.d.ts +26 -0
- package/src/prompt/prompt.utils.js +136 -0
- package/src/prompt/prompt.utils.js.map +1 -0
- package/src/provider/provider.registry.d.ts +12 -5
- package/src/provider/provider.registry.js +30 -138
- package/src/provider/provider.registry.js.map +1 -1
- package/src/regsitry/registry.base.d.ts +1 -1
- package/src/regsitry/registry.base.js.map +1 -1
- package/src/resource/flows/read-resource.flow.d.ts +91 -0
- package/src/resource/flows/read-resource.flow.js +270 -0
- package/src/resource/flows/read-resource.flow.js.map +1 -0
- package/src/resource/flows/resource-templates-list.flow.d.ts +64 -0
- package/src/resource/flows/resource-templates-list.flow.js +191 -0
- package/src/resource/flows/resource-templates-list.flow.js.map +1 -0
- package/src/resource/flows/resources-list.flow.d.ts +64 -0
- package/src/resource/flows/resources-list.flow.js +196 -0
- package/src/resource/flows/resources-list.flow.js.map +1 -0
- package/src/resource/flows/subscribe-resource.flow.d.ts +45 -0
- package/src/resource/flows/subscribe-resource.flow.js +123 -0
- package/src/resource/flows/subscribe-resource.flow.js.map +1 -0
- package/src/resource/flows/unsubscribe-resource.flow.d.ts +44 -0
- package/src/resource/flows/unsubscribe-resource.flow.js +107 -0
- package/src/resource/flows/unsubscribe-resource.flow.js.map +1 -0
- package/src/resource/index.d.ts +8 -0
- package/src/resource/index.js +20 -0
- package/src/resource/index.js.map +1 -0
- package/src/resource/resource.events.d.ts +24 -0
- package/src/resource/resource.events.js +17 -0
- package/src/resource/resource.events.js.map +1 -0
- package/src/resource/resource.instance.d.ts +35 -0
- package/src/resource/resource.instance.js +163 -0
- package/src/resource/resource.instance.js.map +1 -0
- package/src/resource/resource.registry.d.ts +106 -12
- package/src/resource/resource.registry.js +449 -13
- package/src/resource/resource.registry.js.map +1 -1
- package/src/resource/resource.types.d.ts +35 -0
- package/src/resource/resource.types.js +11 -0
- package/src/resource/resource.types.js.map +1 -0
- package/src/resource/resource.utils.d.ts +30 -0
- package/src/resource/resource.utils.js +151 -0
- package/src/resource/resource.utils.js.map +1 -0
- package/src/scope/flows/http.request.flow.d.ts +48 -330
- package/src/scope/flows/http.request.flow.js +306 -78
- package/src/scope/flows/http.request.flow.js.map +1 -1
- package/src/scope/scope.instance.d.ts +12 -0
- package/src/scope/scope.instance.js +145 -15
- package/src/scope/scope.instance.js.map +1 -1
- package/src/tool/flows/call-tool.flow.d.ts +64 -1110
- package/src/tool/flows/call-tool.flow.js +303 -15
- package/src/tool/flows/call-tool.flow.js.map +1 -1
- package/src/tool/flows/tools-list.flow.d.ts +32 -473
- package/src/tool/flows/tools-list.flow.js +111 -10
- package/src/tool/flows/tools-list.flow.js.map +1 -1
- package/src/tool/tool.events.d.ts +8 -1
- package/src/tool/tool.events.js.map +1 -1
- package/src/tool/tool.instance.d.ts +3 -1
- package/src/tool/tool.instance.js +17 -3
- package/src/tool/tool.instance.js.map +1 -1
- package/src/tool/tool.registry.d.ts +7 -1
- package/src/tool/tool.registry.js +26 -10
- package/src/tool/tool.registry.js.map +1 -1
- package/src/tool/tool.types.d.ts +4 -4
- package/src/tool/tool.types.js.map +1 -1
- package/src/tool/tool.utils.d.ts +3 -12
- package/src/tool/tool.utils.js +39 -193
- package/src/tool/tool.utils.js.map +1 -1
- package/src/tool/ui/index.d.ts +22 -0
- package/src/tool/ui/index.js +63 -0
- package/src/tool/ui/index.js.map +1 -0
- package/src/tool/ui/platform-adapters.d.ts +10 -0
- package/src/tool/ui/platform-adapters.js +18 -0
- package/src/tool/ui/platform-adapters.js.map +1 -0
- package/src/tool/ui/template-helpers.d.ts +46 -0
- package/src/tool/ui/template-helpers.js +112 -0
- package/src/tool/ui/template-helpers.js.map +1 -0
- package/src/tool/ui/ui-resource-template.d.ts +34 -0
- package/src/tool/ui/ui-resource-template.js +64 -0
- package/src/tool/ui/ui-resource-template.js.map +1 -0
- package/src/tool/ui/ui-resource.handler.d.ts +74 -0
- package/src/tool/ui/ui-resource.handler.js +129 -0
- package/src/tool/ui/ui-resource.handler.js.map +1 -0
- package/src/transport/adapters/transport.local.adapter.d.ts +2 -2
- package/src/transport/adapters/transport.local.adapter.js +28 -7
- package/src/transport/adapters/transport.local.adapter.js.map +1 -1
- package/src/transport/adapters/transport.sse.adapter.d.ts +2 -2
- package/src/transport/adapters/transport.sse.adapter.js +4 -3
- package/src/transport/adapters/transport.sse.adapter.js.map +1 -1
- package/src/transport/adapters/transport.streamable-http.adapter.d.ts +10 -3
- package/src/transport/adapters/transport.streamable-http.adapter.js +54 -8
- package/src/transport/adapters/transport.streamable-http.adapter.js.map +1 -1
- package/src/transport/flows/handle.sse.flow.d.ts +29 -63
- package/src/transport/flows/handle.sse.flow.js +78 -10
- package/src/transport/flows/handle.sse.flow.js.map +1 -1
- package/src/transport/flows/handle.stateless-http.flow.d.ts +29 -0
- package/src/transport/flows/handle.stateless-http.flow.js +102 -0
- package/src/transport/flows/handle.stateless-http.flow.js.map +1 -0
- package/src/transport/flows/handle.streamable-http.flow.d.ts +32 -64
- package/src/transport/flows/handle.streamable-http.flow.js +158 -26
- package/src/transport/flows/handle.streamable-http.flow.js.map +1 -1
- package/src/transport/legacy/legacy.sse.tranporter.d.ts +9 -0
- package/src/transport/legacy/legacy.sse.tranporter.js +17 -2
- package/src/transport/legacy/legacy.sse.tranporter.js.map +1 -1
- package/src/transport/mcp-handlers/call-tool-request.handler.js +27 -1
- package/src/transport/mcp-handlers/call-tool-request.handler.js.map +1 -1
- package/src/transport/mcp-handlers/complete-request.handler.d.ts +69 -0
- package/src/transport/mcp-handlers/complete-request.handler.js +11 -0
- package/src/transport/mcp-handlers/complete-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/get-prompt-request.handler.d.ts +87 -0
- package/src/transport/mcp-handlers/get-prompt-request.handler.js +11 -0
- package/src/transport/mcp-handlers/get-prompt-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/index.d.ts +517 -208
- package/src/transport/mcp-handlers/index.js +39 -2
- package/src/transport/mcp-handlers/index.js.map +1 -1
- package/src/transport/mcp-handlers/initialize-request.handler.d.ts +1 -1
- package/src/transport/mcp-handlers/initialize-request.handler.js +73 -7
- package/src/transport/mcp-handlers/initialize-request.handler.js.map +1 -1
- package/src/transport/mcp-handlers/list-prompts-request.handler.d.ts +54 -0
- package/src/transport/mcp-handlers/list-prompts-request.handler.js +11 -0
- package/src/transport/mcp-handlers/list-prompts-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/list-resource-templates-request.handler.d.ts +51 -0
- package/src/transport/mcp-handlers/list-resource-templates-request.handler.js +12 -0
- package/src/transport/mcp-handlers/list-resource-templates-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/list-resources-request.handler.d.ts +51 -0
- package/src/transport/mcp-handlers/list-resources-request.handler.js +12 -0
- package/src/transport/mcp-handlers/list-resources-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/list-tools-request.handler.d.ts +19 -146
- package/src/transport/mcp-handlers/logging-set-level-request.handler.d.ts +46 -0
- package/src/transport/mcp-handlers/logging-set-level-request.handler.js +34 -0
- package/src/transport/mcp-handlers/logging-set-level-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/mcp-handlers.types.d.ts +3 -7
- package/src/transport/mcp-handlers/mcp-handlers.types.js.map +1 -1
- package/src/transport/mcp-handlers/read-resource-request.handler.d.ts +46 -0
- package/src/transport/mcp-handlers/read-resource-request.handler.js +12 -0
- package/src/transport/mcp-handlers/read-resource-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/roots-list-changed-notification.handler.d.ts +11 -0
- package/src/transport/mcp-handlers/roots-list-changed-notification.handler.js +26 -0
- package/src/transport/mcp-handlers/roots-list-changed-notification.handler.js.map +1 -0
- package/src/transport/mcp-handlers/subscribe-request.handler.d.ts +37 -0
- package/src/transport/mcp-handlers/subscribe-request.handler.js +34 -0
- package/src/transport/mcp-handlers/subscribe-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/unsubscribe-request.handler.d.ts +37 -0
- package/src/transport/mcp-handlers/unsubscribe-request.handler.js +34 -0
- package/src/transport/mcp-handlers/unsubscribe-request.handler.js.map +1 -0
- package/src/transport/transport.local.js +7 -2
- package/src/transport/transport.local.js.map +1 -1
- package/src/transport/transport.registry.d.ts +30 -0
- package/src/transport/transport.registry.js +84 -1
- package/src/transport/transport.registry.js.map +1 -1
- package/src/transport/transport.types.d.ts +3 -3
- package/src/transport/transport.types.js.map +1 -1
- package/src/utils/content.utils.d.ts +48 -0
- package/src/utils/content.utils.js +194 -0
- package/src/utils/content.utils.js.map +1 -0
- package/src/utils/index.d.ts +8 -0
- package/src/utils/index.js +55 -0
- package/src/utils/index.js.map +1 -0
- package/src/utils/lineage.utils.d.ts +40 -0
- package/src/utils/lineage.utils.js +82 -0
- package/src/utils/lineage.utils.js.map +1 -0
- package/src/utils/naming.utils.d.ts +46 -0
- package/src/utils/naming.utils.js +136 -0
- package/src/utils/naming.utils.js.map +1 -0
- package/src/utils/types.utils.d.ts +2 -2
- package/src/utils/types.utils.js.map +1 -1
- package/src/utils/uri-template.utils.d.ts +57 -0
- package/src/utils/uri-template.utils.js +113 -0
- package/src/utils/uri-template.utils.js.map +1 -0
- package/src/utils/uri-validation.utils.d.ts +40 -0
- package/src/utils/uri-validation.utils.js +76 -0
- package/src/utils/uri-validation.utils.js.map +1 -0
- package/src/__test-utils__/fixtures/hook.fixtures.d.ts +0 -46
- package/src/__test-utils__/fixtures/hook.fixtures.js +0 -114
- package/src/__test-utils__/fixtures/hook.fixtures.js.map +0 -1
- package/src/__test-utils__/fixtures/index.d.ts +0 -7
- package/src/__test-utils__/fixtures/index.js +0 -11
- package/src/__test-utils__/fixtures/index.js.map +0 -1
- package/src/__test-utils__/fixtures/plugin.fixtures.d.ts +0 -46
- package/src/__test-utils__/fixtures/plugin.fixtures.js +0 -127
- package/src/__test-utils__/fixtures/plugin.fixtures.js.map +0 -1
- package/src/__test-utils__/fixtures/provider.fixtures.d.ts +0 -69
- package/src/__test-utils__/fixtures/provider.fixtures.js +0 -131
- package/src/__test-utils__/fixtures/provider.fixtures.js.map +0 -1
- package/src/__test-utils__/fixtures/scope.fixtures.d.ts +0 -14
- package/src/__test-utils__/fixtures/scope.fixtures.js +0 -59
- package/src/__test-utils__/fixtures/scope.fixtures.js.map +0 -1
- package/src/__test-utils__/fixtures/tool.fixtures.d.ts +0 -36
- package/src/__test-utils__/fixtures/tool.fixtures.js +0 -91
- package/src/__test-utils__/fixtures/tool.fixtures.js.map +0 -1
- package/src/__test-utils__/helpers/assertion.helpers.d.ts +0 -45
- package/src/__test-utils__/helpers/assertion.helpers.js +0 -153
- package/src/__test-utils__/helpers/assertion.helpers.js.map +0 -1
- package/src/__test-utils__/helpers/async.helpers.d.ts +0 -48
- package/src/__test-utils__/helpers/async.helpers.js +0 -112
- package/src/__test-utils__/helpers/async.helpers.js.map +0 -1
- package/src/__test-utils__/helpers/index.d.ts +0 -6
- package/src/__test-utils__/helpers/index.js +0 -10
- package/src/__test-utils__/helpers/index.js.map +0 -1
- package/src/__test-utils__/helpers/setup.helpers.d.ts +0 -54
- package/src/__test-utils__/helpers/setup.helpers.js +0 -106
- package/src/__test-utils__/helpers/setup.helpers.js.map +0 -1
- package/src/__test-utils__/index.d.ts +0 -9
- package/src/__test-utils__/index.js +0 -14
- package/src/__test-utils__/index.js.map +0 -1
- package/src/__test-utils__/mocks/flow-instance.mock.d.ts +0 -50
- package/src/__test-utils__/mocks/flow-instance.mock.js +0 -72
- package/src/__test-utils__/mocks/flow-instance.mock.js.map +0 -1
- package/src/__test-utils__/mocks/hook-registry.mock.d.ts +0 -25
- package/src/__test-utils__/mocks/hook-registry.mock.js +0 -65
- package/src/__test-utils__/mocks/hook-registry.mock.js.map +0 -1
- package/src/__test-utils__/mocks/index.d.ts +0 -8
- package/src/__test-utils__/mocks/index.js +0 -12
- package/src/__test-utils__/mocks/index.js.map +0 -1
- package/src/__test-utils__/mocks/plugin-registry.mock.d.ts +0 -43
- package/src/__test-utils__/mocks/plugin-registry.mock.js +0 -70
- package/src/__test-utils__/mocks/plugin-registry.mock.js.map +0 -1
- package/src/__test-utils__/mocks/provider-registry.mock.d.ts +0 -39
- package/src/__test-utils__/mocks/provider-registry.mock.js +0 -72
- package/src/__test-utils__/mocks/provider-registry.mock.js.map +0 -1
- package/src/__test-utils__/mocks/tool-registry.mock.d.ts +0 -43
- package/src/__test-utils__/mocks/tool-registry.mock.js +0 -79
- package/src/__test-utils__/mocks/tool-registry.mock.js.map +0 -1
- package/src/auth/path.utils.d.ts +0 -20
- package/src/auth/path.utils.js +0 -71
- package/src/auth/path.utils.js.map +0 -1
- package/src/common/decorators-old/async-with.decorator.d.ts +0 -10
- package/src/common/decorators-old/async-with.decorator.js +0 -24
- package/src/common/decorators-old/async-with.decorator.js.map +0 -1
- package/src/common/decorators-old/auth-hook.decorator.d.ts +0 -14
- package/src/common/decorators-old/auth-hook.decorator.js +0 -27
- package/src/common/decorators-old/auth-hook.decorator.js.map +0 -1
- package/src/common/decorators-old/session-hook.decorator.d.ts +0 -14
- package/src/common/decorators-old/session-hook.decorator.js +0 -27
- package/src/common/decorators-old/session-hook.decorator.js.map +0 -1
|
@@ -1,18 +1,105 @@
|
|
|
1
1
|
import { URL } from 'url';
|
|
2
|
-
import { FrontMcpAuth, FrontMcpLogger,
|
|
2
|
+
import { FrontMcpAuth, FrontMcpLogger, ScopeEntry, ServerRequest, JWK } from '../../common';
|
|
3
|
+
import { PublicAuthOptions, OrchestratedLocalOptions, OrchestratedRemoteOptions } from '../../common/types/options/auth.options';
|
|
3
4
|
import ProviderRegistry from '../../provider/provider.registry';
|
|
4
|
-
|
|
5
|
+
import { AuthorizationStore } from '../session/authorization.store';
|
|
6
|
+
/**
|
|
7
|
+
* Options type for LocalPrimaryAuth - can be public, orchestrated local, or orchestrated remote
|
|
8
|
+
*/
|
|
9
|
+
export type LocalPrimaryAuthOptions = PublicAuthOptions | OrchestratedLocalOptions | OrchestratedRemoteOptions;
|
|
10
|
+
/**
|
|
11
|
+
* User information for JWT claims
|
|
12
|
+
*/
|
|
13
|
+
export interface UserInfo {
|
|
14
|
+
sub: string;
|
|
15
|
+
email?: string;
|
|
16
|
+
name?: string;
|
|
17
|
+
picture?: string;
|
|
18
|
+
roles?: string[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Token response from the token endpoint
|
|
22
|
+
*/
|
|
23
|
+
export interface TokenResponse {
|
|
24
|
+
access_token: string;
|
|
25
|
+
token_type: 'Bearer';
|
|
26
|
+
expires_in: number;
|
|
27
|
+
refresh_token?: string;
|
|
28
|
+
scope?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Consent and federated login metadata for JWT claims
|
|
32
|
+
*/
|
|
33
|
+
export interface ConsentMetadata {
|
|
34
|
+
selectedToolIds?: string[];
|
|
35
|
+
selectedProviderIds?: string[];
|
|
36
|
+
skippedProviderIds?: string[];
|
|
37
|
+
consentEnabled?: boolean;
|
|
38
|
+
federatedLoginUsed?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export declare class LocalPrimaryAuth extends FrontMcpAuth<LocalPrimaryAuthOptions> {
|
|
5
41
|
private scope;
|
|
6
42
|
private providers;
|
|
7
43
|
readonly host: string;
|
|
8
44
|
readonly port: number;
|
|
9
45
|
readonly issuer: string;
|
|
10
|
-
readonly keys:
|
|
46
|
+
readonly keys: JWK[];
|
|
11
47
|
readonly secret: Uint8Array;
|
|
12
48
|
readonly logger: FrontMcpLogger;
|
|
49
|
+
readonly authorizationStore: AuthorizationStore;
|
|
13
50
|
private jwks;
|
|
14
|
-
|
|
51
|
+
/** Default access token TTL (1 hour) */
|
|
52
|
+
private readonly accessTokenTtlSeconds;
|
|
53
|
+
/** Default refresh token TTL (30 days) */
|
|
54
|
+
private readonly refreshTokenTtlSeconds;
|
|
55
|
+
/**
|
|
56
|
+
* Get the authorization store as InMemoryAuthorizationStore with type guard.
|
|
57
|
+
* This ensures type safety when using InMemory-specific methods.
|
|
58
|
+
*/
|
|
59
|
+
private getInMemoryStore;
|
|
60
|
+
constructor(scope: ScopeEntry, providers: ProviderRegistry, options: LocalPrimaryAuthOptions);
|
|
61
|
+
/**
|
|
62
|
+
* Derive issuer from options
|
|
63
|
+
*/
|
|
64
|
+
private deriveIssuer;
|
|
15
65
|
signAnonymousJwt(): Promise<string>;
|
|
66
|
+
/**
|
|
67
|
+
* Sign an access token for an authenticated user
|
|
68
|
+
*/
|
|
69
|
+
signAccessToken(user: UserInfo, scopes: string[], audience?: string, consentMetadata?: ConsentMetadata): Promise<string>;
|
|
70
|
+
/**
|
|
71
|
+
* Exchange an authorization code for tokens
|
|
72
|
+
*/
|
|
73
|
+
exchangeCode(code: string, clientId: string, redirectUri: string, codeVerifier: string): Promise<TokenResponse | {
|
|
74
|
+
error: string;
|
|
75
|
+
error_description: string;
|
|
76
|
+
}>;
|
|
77
|
+
/**
|
|
78
|
+
* Refresh an access token using a refresh token
|
|
79
|
+
*/
|
|
80
|
+
refreshAccessToken(refreshToken: string, clientId: string): Promise<TokenResponse | {
|
|
81
|
+
error: string;
|
|
82
|
+
error_description: string;
|
|
83
|
+
}>;
|
|
84
|
+
/**
|
|
85
|
+
* Create an authorization code for a user (called after login)
|
|
86
|
+
*/
|
|
87
|
+
createAuthorizationCode(params: {
|
|
88
|
+
clientId: string;
|
|
89
|
+
redirectUri: string;
|
|
90
|
+
scopes: string[];
|
|
91
|
+
codeChallenge: string;
|
|
92
|
+
userSub: string;
|
|
93
|
+
userEmail?: string;
|
|
94
|
+
userName?: string;
|
|
95
|
+
state?: string;
|
|
96
|
+
resource?: string;
|
|
97
|
+
selectedToolIds?: string[];
|
|
98
|
+
selectedProviderIds?: string[];
|
|
99
|
+
skippedProviderIds?: string[];
|
|
100
|
+
consentEnabled?: boolean;
|
|
101
|
+
federatedLoginUsed?: boolean;
|
|
102
|
+
}): Promise<string>;
|
|
16
103
|
protected initialize(): Promise<void>;
|
|
17
104
|
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
18
105
|
validate(request: ServerRequest): Promise<void>;
|
|
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const jose_1 = require("jose");
|
|
6
6
|
const crypto_1 = require("crypto");
|
|
7
7
|
const common_1 = require("../../common");
|
|
8
|
+
const auth_options_1 = require("../../common/types/options/auth.options");
|
|
8
9
|
const well_known_prm_flow_1 = tslib_1.__importDefault(require("../flows/well-known.prm.flow"));
|
|
9
10
|
const well_known_oauth_authorization_server_flow_1 = tslib_1.__importDefault(require("../flows/well-known.oauth-authorization-server.flow"));
|
|
10
11
|
const well_known_jwks_flow_1 = tslib_1.__importDefault(require("../flows/well-known.jwks.flow"));
|
|
@@ -12,7 +13,9 @@ const session_verify_flow_1 = tslib_1.__importDefault(require("../flows/session.
|
|
|
12
13
|
const oauth_authorize_flow_1 = tslib_1.__importDefault(require("../flows/oauth.authorize.flow"));
|
|
13
14
|
const oauth_register_flow_1 = tslib_1.__importDefault(require("../flows/oauth.register.flow"));
|
|
14
15
|
const oauth_token_flow_1 = tslib_1.__importDefault(require("../flows/oauth.token.flow"));
|
|
16
|
+
const oauth_callback_flow_1 = tslib_1.__importDefault(require("../flows/oauth.callback.flow"));
|
|
15
17
|
const jwks_1 = require("../jwks");
|
|
18
|
+
const authorization_store_1 = require("../session/authorization.store");
|
|
16
19
|
const DEFAULT_NO_AUTH_SECRET = (0, crypto_1.randomBytes)(32);
|
|
17
20
|
class LocalPrimaryAuth extends common_1.FrontMcpAuth {
|
|
18
21
|
scope;
|
|
@@ -23,24 +26,60 @@ class LocalPrimaryAuth extends common_1.FrontMcpAuth {
|
|
|
23
26
|
keys = [];
|
|
24
27
|
secret;
|
|
25
28
|
logger;
|
|
29
|
+
authorizationStore;
|
|
26
30
|
jwks = new jwks_1.JwksService();
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
/** Default access token TTL (1 hour) */
|
|
32
|
+
accessTokenTtlSeconds = 3600;
|
|
33
|
+
/** Default refresh token TTL (30 days) */
|
|
34
|
+
refreshTokenTtlSeconds = 30 * 24 * 3600;
|
|
35
|
+
/**
|
|
36
|
+
* Get the authorization store as InMemoryAuthorizationStore with type guard.
|
|
37
|
+
* This ensures type safety when using InMemory-specific methods.
|
|
38
|
+
*/
|
|
39
|
+
getInMemoryStore() {
|
|
40
|
+
if (!(this.authorizationStore instanceof authorization_store_1.InMemoryAuthorizationStore)) {
|
|
41
|
+
throw new Error('LocalPrimaryAuth requires InMemoryAuthorizationStore for record creation methods');
|
|
42
|
+
}
|
|
43
|
+
return this.authorizationStore;
|
|
44
|
+
}
|
|
45
|
+
constructor(scope, providers, options) {
|
|
46
|
+
super(options);
|
|
29
47
|
this.scope = scope;
|
|
30
48
|
this.providers = providers;
|
|
31
49
|
this.logger = this.providers.getActiveScope().logger.child('LocalPrimaryAuth');
|
|
32
50
|
this.port = this.providers.getActiveScope().metadata.http?.port ?? 3001;
|
|
33
51
|
this.host = 'localhost';
|
|
34
|
-
this.issuer =
|
|
35
|
-
if (process.env[
|
|
36
|
-
this.secret = new TextEncoder().encode(process.env[
|
|
52
|
+
this.issuer = this.deriveIssuer(options);
|
|
53
|
+
if (process.env['JWT_SECRET']) {
|
|
54
|
+
this.secret = new TextEncoder().encode(process.env['JWT_SECRET']);
|
|
37
55
|
}
|
|
38
56
|
else {
|
|
39
57
|
this.logger.warn('JWT_SECRET is not set, using default secret');
|
|
40
58
|
this.secret = DEFAULT_NO_AUTH_SECRET;
|
|
41
59
|
}
|
|
60
|
+
// Initialize authorization store (in-memory for now, Redis later)
|
|
61
|
+
this.authorizationStore = new authorization_store_1.InMemoryAuthorizationStore();
|
|
42
62
|
this.ready = this.initialize();
|
|
43
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Derive issuer from options
|
|
66
|
+
*/
|
|
67
|
+
deriveIssuer(options) {
|
|
68
|
+
const basePath = `http://${this.host}:${this.port}${this.scope.fullPath}`;
|
|
69
|
+
if ((0, auth_options_1.isPublicMode)(options)) {
|
|
70
|
+
return options.issuer ?? basePath;
|
|
71
|
+
}
|
|
72
|
+
if ((0, auth_options_1.isOrchestratedMode)(options)) {
|
|
73
|
+
if ((0, auth_options_1.isOrchestratedLocal)(options)) {
|
|
74
|
+
return options.local?.issuer ?? basePath;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Orchestrated remote
|
|
78
|
+
return options.local?.issuer ?? basePath;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return basePath;
|
|
82
|
+
}
|
|
44
83
|
async signAnonymousJwt() {
|
|
45
84
|
const sub = (0, crypto_1.randomUUID)();
|
|
46
85
|
return new jose_1.SignJWT({ sub, role: 'user', anonymous: true })
|
|
@@ -50,6 +89,197 @@ class LocalPrimaryAuth extends common_1.FrontMcpAuth {
|
|
|
50
89
|
.setExpirationTime('1d')
|
|
51
90
|
.sign(this.secret);
|
|
52
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Sign an access token for an authenticated user
|
|
94
|
+
*/
|
|
95
|
+
async signAccessToken(user, scopes, audience, consentMetadata) {
|
|
96
|
+
const claims = {
|
|
97
|
+
sub: user.sub,
|
|
98
|
+
scope: scopes.join(' '),
|
|
99
|
+
};
|
|
100
|
+
if (user.email)
|
|
101
|
+
claims['email'] = user.email;
|
|
102
|
+
if (user.name)
|
|
103
|
+
claims['name'] = user.name;
|
|
104
|
+
if (user.picture)
|
|
105
|
+
claims['picture'] = user.picture;
|
|
106
|
+
if (user.roles)
|
|
107
|
+
claims['roles'] = user.roles;
|
|
108
|
+
// Add consent metadata if present
|
|
109
|
+
if (consentMetadata) {
|
|
110
|
+
if (consentMetadata.consentEnabled) {
|
|
111
|
+
claims['consent'] = {
|
|
112
|
+
enabled: true,
|
|
113
|
+
selectedTools: consentMetadata.selectedToolIds ?? [],
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (consentMetadata.federatedLoginUsed) {
|
|
117
|
+
claims['federated'] = {
|
|
118
|
+
enabled: true,
|
|
119
|
+
selectedProviders: consentMetadata.selectedProviderIds ?? [],
|
|
120
|
+
skippedProviders: consentMetadata.skippedProviderIds ?? [],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const jwt = new jose_1.SignJWT(claims)
|
|
125
|
+
.setProtectedHeader({ alg: 'HS256', typ: 'JWT' })
|
|
126
|
+
.setIssuedAt()
|
|
127
|
+
.setIssuer(this.issuer)
|
|
128
|
+
.setExpirationTime(`${this.accessTokenTtlSeconds}s`)
|
|
129
|
+
.setJti((0, crypto_1.randomUUID)());
|
|
130
|
+
if (audience) {
|
|
131
|
+
jwt.setAudience(audience);
|
|
132
|
+
}
|
|
133
|
+
return jwt.sign(this.secret);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Exchange an authorization code for tokens
|
|
137
|
+
*/
|
|
138
|
+
async exchangeCode(code, clientId, redirectUri, codeVerifier) {
|
|
139
|
+
// Get the authorization code record
|
|
140
|
+
const codeRecord = await this.authorizationStore.getAuthorizationCode(code);
|
|
141
|
+
if (!codeRecord) {
|
|
142
|
+
this.logger.warn(`Authorization code not found or expired: ${code.substring(0, 8)}...`);
|
|
143
|
+
return {
|
|
144
|
+
error: 'invalid_grant',
|
|
145
|
+
error_description: 'Authorization code is invalid or expired',
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
// Verify code hasn't been used (single-use)
|
|
149
|
+
if (codeRecord.used) {
|
|
150
|
+
this.logger.warn(`Authorization code already used: ${code.substring(0, 8)}...`);
|
|
151
|
+
// Security: If a code is reused, revoke all tokens from this code
|
|
152
|
+
await this.authorizationStore.deleteAuthorizationCode(code);
|
|
153
|
+
return {
|
|
154
|
+
error: 'invalid_grant',
|
|
155
|
+
error_description: 'Authorization code has already been used',
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
// Verify client_id matches
|
|
159
|
+
if (codeRecord.clientId !== clientId) {
|
|
160
|
+
this.logger.warn(`Client ID mismatch: expected ${codeRecord.clientId}, got ${clientId}`);
|
|
161
|
+
return {
|
|
162
|
+
error: 'invalid_grant',
|
|
163
|
+
error_description: 'Client ID does not match',
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// Verify redirect_uri matches
|
|
167
|
+
if (codeRecord.redirectUri !== redirectUri) {
|
|
168
|
+
this.logger.warn(`Redirect URI mismatch`);
|
|
169
|
+
return {
|
|
170
|
+
error: 'invalid_grant',
|
|
171
|
+
error_description: 'Redirect URI does not match',
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
// Verify PKCE
|
|
175
|
+
if (!(0, authorization_store_1.verifyPkce)(codeVerifier, codeRecord.pkce)) {
|
|
176
|
+
this.logger.warn(`PKCE verification failed`);
|
|
177
|
+
return {
|
|
178
|
+
error: 'invalid_grant',
|
|
179
|
+
error_description: 'PKCE verification failed',
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// Mark code as used
|
|
183
|
+
await this.authorizationStore.markCodeUsed(code);
|
|
184
|
+
// Generate tokens
|
|
185
|
+
const user = {
|
|
186
|
+
sub: codeRecord.userSub,
|
|
187
|
+
email: codeRecord.userEmail,
|
|
188
|
+
name: codeRecord.userName,
|
|
189
|
+
};
|
|
190
|
+
// Build consent metadata from code record
|
|
191
|
+
const consentMetadata = codeRecord.consentEnabled || codeRecord.federatedLoginUsed
|
|
192
|
+
? {
|
|
193
|
+
selectedToolIds: codeRecord.selectedToolIds,
|
|
194
|
+
selectedProviderIds: codeRecord.selectedProviderIds,
|
|
195
|
+
skippedProviderIds: codeRecord.skippedProviderIds,
|
|
196
|
+
consentEnabled: codeRecord.consentEnabled,
|
|
197
|
+
federatedLoginUsed: codeRecord.federatedLoginUsed,
|
|
198
|
+
}
|
|
199
|
+
: undefined;
|
|
200
|
+
const accessToken = await this.signAccessToken(user, codeRecord.scopes, codeRecord.resource, consentMetadata);
|
|
201
|
+
// Create refresh token
|
|
202
|
+
const refreshTokenRecord = this.getInMemoryStore().createRefreshTokenRecord({
|
|
203
|
+
clientId,
|
|
204
|
+
userSub: user.sub,
|
|
205
|
+
scopes: codeRecord.scopes,
|
|
206
|
+
resource: codeRecord.resource,
|
|
207
|
+
});
|
|
208
|
+
await this.authorizationStore.storeRefreshToken(refreshTokenRecord);
|
|
209
|
+
this.logger.info(`Tokens issued for user: ${user.sub}`);
|
|
210
|
+
return {
|
|
211
|
+
access_token: accessToken,
|
|
212
|
+
token_type: 'Bearer',
|
|
213
|
+
expires_in: this.accessTokenTtlSeconds,
|
|
214
|
+
refresh_token: refreshTokenRecord.token,
|
|
215
|
+
scope: codeRecord.scopes.join(' '),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Refresh an access token using a refresh token
|
|
220
|
+
*/
|
|
221
|
+
async refreshAccessToken(refreshToken, clientId) {
|
|
222
|
+
const tokenRecord = await this.authorizationStore.getRefreshToken(refreshToken);
|
|
223
|
+
if (!tokenRecord) {
|
|
224
|
+
this.logger.warn('Refresh token not found or expired');
|
|
225
|
+
return {
|
|
226
|
+
error: 'invalid_grant',
|
|
227
|
+
error_description: 'Refresh token is invalid or expired',
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
if (tokenRecord.clientId !== clientId) {
|
|
231
|
+
this.logger.warn('Client ID mismatch on refresh');
|
|
232
|
+
return {
|
|
233
|
+
error: 'invalid_grant',
|
|
234
|
+
error_description: 'Client ID does not match',
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
// Generate new access token
|
|
238
|
+
const user = { sub: tokenRecord.userSub };
|
|
239
|
+
const accessToken = await this.signAccessToken(user, tokenRecord.scopes, tokenRecord.resource);
|
|
240
|
+
// Rotate refresh token
|
|
241
|
+
const newRefreshRecord = this.getInMemoryStore().createRefreshTokenRecord({
|
|
242
|
+
clientId,
|
|
243
|
+
userSub: tokenRecord.userSub,
|
|
244
|
+
scopes: tokenRecord.scopes,
|
|
245
|
+
resource: tokenRecord.resource,
|
|
246
|
+
});
|
|
247
|
+
await this.authorizationStore.rotateRefreshToken(refreshToken, newRefreshRecord);
|
|
248
|
+
this.logger.info(`Tokens refreshed for user: ${user.sub}`);
|
|
249
|
+
return {
|
|
250
|
+
access_token: accessToken,
|
|
251
|
+
token_type: 'Bearer',
|
|
252
|
+
expires_in: this.accessTokenTtlSeconds,
|
|
253
|
+
refresh_token: newRefreshRecord.token,
|
|
254
|
+
scope: tokenRecord.scopes.join(' '),
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Create an authorization code for a user (called after login)
|
|
259
|
+
*/
|
|
260
|
+
async createAuthorizationCode(params) {
|
|
261
|
+
const store = this.getInMemoryStore();
|
|
262
|
+
const codeRecord = store.createCodeRecord({
|
|
263
|
+
clientId: params.clientId,
|
|
264
|
+
redirectUri: params.redirectUri,
|
|
265
|
+
scopes: params.scopes,
|
|
266
|
+
pkce: { challenge: params.codeChallenge, method: 'S256' },
|
|
267
|
+
userSub: params.userSub,
|
|
268
|
+
userEmail: params.userEmail,
|
|
269
|
+
userName: params.userName,
|
|
270
|
+
state: params.state,
|
|
271
|
+
resource: params.resource,
|
|
272
|
+
// Consent and Federated Login Data
|
|
273
|
+
selectedToolIds: params.selectedToolIds,
|
|
274
|
+
selectedProviderIds: params.selectedProviderIds,
|
|
275
|
+
skippedProviderIds: params.skippedProviderIds,
|
|
276
|
+
consentEnabled: params.consentEnabled,
|
|
277
|
+
federatedLoginUsed: params.federatedLoginUsed,
|
|
278
|
+
});
|
|
279
|
+
await this.authorizationStore.storeAuthorizationCode(codeRecord);
|
|
280
|
+
this.logger.info(`Authorization code created for user: ${params.userSub}`);
|
|
281
|
+
return codeRecord.code;
|
|
282
|
+
}
|
|
53
283
|
async initialize() {
|
|
54
284
|
// TODO: create separated jwk service for local/remote auth options
|
|
55
285
|
this.providers.injectProvider({
|
|
@@ -71,7 +301,7 @@ class LocalPrimaryAuth extends common_1.FrontMcpAuth {
|
|
|
71
301
|
}
|
|
72
302
|
async registerAuthFlows() {
|
|
73
303
|
const scope = this.providers.getActiveScope();
|
|
74
|
-
await scope.registryFlows(well_known_prm_flow_1.default
|
|
304
|
+
await scope.registryFlows(well_known_prm_flow_1.default /** /.well-known/oauth-protected-resource */, well_known_oauth_authorization_server_flow_1.default /** /.well-known/oauth-authorization-server */, well_known_jwks_flow_1.default /** /.well-known/jwks.json */, session_verify_flow_1.default /** Session verification flow */, oauth_authorize_flow_1.default /** GET /oauth/authorize */, oauth_token_flow_1.default /** POST /oauth/token */, oauth_callback_flow_1.default /** GET /oauth/callback - login callback */, oauth_register_flow_1.default /** POST /oauth/register */);
|
|
75
305
|
}
|
|
76
306
|
}
|
|
77
307
|
exports.LocalPrimaryAuth = LocalPrimaryAuth;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance.local-primary-auth.js","sourceRoot":"","sources":["../../../../src/auth/instances/instance.local-primary-auth.ts"],"names":[],"mappings":"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","sourcesContent":["import {SignJWT} from \"jose\";\nimport {URL} from 'url';\nimport {randomBytes, randomUUID} from \"crypto\";\nimport {FrontMcpAuth, FrontMcpLogger, LocalAuthOptions, ProviderScope, ScopeEntry, ServerRequest} from '../../common';\nimport ProviderRegistry from '../../provider/provider.registry';\nimport WellKnownPrmFlow from '../flows/well-known.prm.flow';\nimport WellKnownAsFlow from '../flows/well-known.oauth-authorization-server.flow';\nimport WellKnownJwksFlow from '../flows/well-known.jwks.flow';\nimport SessionVerifyFlow from '../flows/session.verify.flow';\nimport OauthAuthorizeFlow from \"../flows/oauth.authorize.flow\";\nimport OauthRegisterFlow from \"../flows/oauth.register.flow\";\nimport OauthTokenFlow from \"../flows/oauth.token.flow\";\nimport {JwksService} from \"../jwks\";\n\n\nconst DEFAULT_NO_AUTH_SECRET = randomBytes(32)\n\nexport class LocalPrimaryAuth extends FrontMcpAuth {\n readonly host: string;\n readonly port: number;\n readonly issuer: string;\n readonly keys: any[] = [];\n readonly secret: Uint8Array;\n readonly logger: FrontMcpLogger;\n private jwks = new JwksService();\n\n constructor(private scope:ScopeEntry,private providers: ProviderRegistry, metadata: LocalAuthOptions) {\n super(metadata);\n this.logger = this.providers.getActiveScope().logger.child('LocalPrimaryAuth');\n this.port = this.providers.getActiveScope().metadata.http?.port ?? 3001;\n this.host = 'localhost';\n this.issuer = `http://${this.host}:${this.port}${scope.fullPath}`\n\n if (process.env[\"JWT_SECRET\"]) {\n this.secret = new TextEncoder().encode(process.env[\"JWT_SECRET\"])\n } else {\n this.logger.warn('JWT_SECRET is not set, using default secret')\n this.secret = DEFAULT_NO_AUTH_SECRET;\n }\n this.ready = this.initialize();\n }\n\n\n async signAnonymousJwt() {\n const sub = randomUUID()\n return new SignJWT({sub, role: 'user', anonymous: true})\n .setProtectedHeader({alg: 'HS256', typ: 'JWT'})\n .setIssuedAt()\n .setIssuer(this.issuer)\n .setExpirationTime('1d')\n .sign(this.secret)\n }\n\n protected async initialize(): Promise<void> {\n // TODO: create separated jwk service for local/remote auth options\n this.providers.injectProvider({\n value: this.jwks,\n metadata: {\n scope: ProviderScope.GLOBAL,\n name: 'auth:jwk-service',\n },\n provide: JwksService,\n });\n\n await this.registerAuthFlows();\n\n\n return Promise.resolve();\n }\n\n override fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n return fetch(input, init);\n }\n\n override validate(request: ServerRequest): Promise<void> {\n return Promise.resolve();\n }\n\n\n private async registerAuthFlows() {\n const scope = this.providers.getActiveScope();\n await scope.registryFlows(\n WellKnownPrmFlow, /** /.well-known/oauth-protected-resource */\n WellKnownAsFlow, /** /.well-known/oauth-authorization-server */\n WellKnownJwksFlow, /** /.well-known/jwks.json */\n SessionVerifyFlow, /** Session verification flow */\n\n OauthAuthorizeFlow,\n OauthTokenFlow,\n OauthRegisterFlow\n );\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"instance.local-primary-auth.js","sourceRoot":"","sources":["../../../../src/auth/instances/instance.local-primary-auth.ts"],"names":[],"mappings":"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","sourcesContent":["import { SignJWT } from 'jose';\nimport { URL } from 'url';\nimport { randomBytes, randomUUID } from 'crypto';\nimport { FrontMcpAuth, FrontMcpLogger, ProviderScope, ScopeEntry, ServerRequest, JWK } from '../../common';\nimport {\n PublicAuthOptions,\n OrchestratedLocalOptions,\n OrchestratedRemoteOptions,\n isPublicMode,\n isOrchestratedMode,\n isOrchestratedLocal,\n} from '../../common/types/options/auth.options';\nimport ProviderRegistry from '../../provider/provider.registry';\nimport WellKnownPrmFlow from '../flows/well-known.prm.flow';\nimport WellKnownAsFlow from '../flows/well-known.oauth-authorization-server.flow';\nimport WellKnownJwksFlow from '../flows/well-known.jwks.flow';\nimport SessionVerifyFlow from '../flows/session.verify.flow';\nimport OauthAuthorizeFlow from '../flows/oauth.authorize.flow';\nimport OauthRegisterFlow from '../flows/oauth.register.flow';\nimport OauthTokenFlow from '../flows/oauth.token.flow';\nimport OauthCallbackFlow from '../flows/oauth.callback.flow';\nimport { JwksService } from '../jwks';\nimport {\n AuthorizationStore,\n InMemoryAuthorizationStore,\n AuthorizationCodeRecord,\n verifyPkce,\n} from '../session/authorization.store';\n\n/**\n * Options type for LocalPrimaryAuth - can be public, orchestrated local, or orchestrated remote\n */\nexport type LocalPrimaryAuthOptions = PublicAuthOptions | OrchestratedLocalOptions | OrchestratedRemoteOptions;\n\nconst DEFAULT_NO_AUTH_SECRET = randomBytes(32);\n\n/**\n * User information for JWT claims\n */\nexport interface UserInfo {\n sub: string;\n email?: string;\n name?: string;\n picture?: string;\n roles?: string[];\n}\n\n/**\n * Token response from the token endpoint\n */\nexport interface TokenResponse {\n access_token: string;\n token_type: 'Bearer';\n expires_in: number;\n refresh_token?: string;\n scope?: string;\n}\n\n/**\n * Consent and federated login metadata for JWT claims\n */\nexport interface ConsentMetadata {\n selectedToolIds?: string[];\n selectedProviderIds?: string[];\n skippedProviderIds?: string[];\n consentEnabled?: boolean;\n federatedLoginUsed?: boolean;\n}\n\nexport class LocalPrimaryAuth extends FrontMcpAuth<LocalPrimaryAuthOptions> {\n readonly host: string;\n readonly port: number;\n readonly issuer: string;\n readonly keys: JWK[] = [];\n readonly secret: Uint8Array;\n readonly logger: FrontMcpLogger;\n readonly authorizationStore: AuthorizationStore;\n private jwks = new JwksService();\n\n /** Default access token TTL (1 hour) */\n private readonly accessTokenTtlSeconds = 3600;\n /** Default refresh token TTL (30 days) */\n private readonly refreshTokenTtlSeconds = 30 * 24 * 3600;\n\n /**\n * Get the authorization store as InMemoryAuthorizationStore with type guard.\n * This ensures type safety when using InMemory-specific methods.\n */\n private getInMemoryStore(): InMemoryAuthorizationStore {\n if (!(this.authorizationStore instanceof InMemoryAuthorizationStore)) {\n throw new Error('LocalPrimaryAuth requires InMemoryAuthorizationStore for record creation methods');\n }\n return this.authorizationStore;\n }\n\n constructor(private scope: ScopeEntry, private providers: ProviderRegistry, options: LocalPrimaryAuthOptions) {\n super(options);\n this.logger = this.providers.getActiveScope().logger.child('LocalPrimaryAuth');\n this.port = this.providers.getActiveScope().metadata.http?.port ?? 3001;\n this.host = 'localhost';\n this.issuer = this.deriveIssuer(options);\n\n if (process.env['JWT_SECRET']) {\n this.secret = new TextEncoder().encode(process.env['JWT_SECRET']);\n } else {\n this.logger.warn('JWT_SECRET is not set, using default secret');\n this.secret = DEFAULT_NO_AUTH_SECRET;\n }\n\n // Initialize authorization store (in-memory for now, Redis later)\n this.authorizationStore = new InMemoryAuthorizationStore();\n\n this.ready = this.initialize();\n }\n\n /**\n * Derive issuer from options\n */\n private deriveIssuer(options: LocalPrimaryAuthOptions): string {\n const basePath = `http://${this.host}:${this.port}${this.scope.fullPath}`;\n\n if (isPublicMode(options)) {\n return options.issuer ?? basePath;\n }\n\n if (isOrchestratedMode(options)) {\n if (isOrchestratedLocal(options)) {\n return options.local?.issuer ?? basePath;\n } else {\n // Orchestrated remote\n return options.local?.issuer ?? basePath;\n }\n }\n\n return basePath;\n }\n\n async signAnonymousJwt() {\n const sub = randomUUID();\n return new SignJWT({ sub, role: 'user', anonymous: true })\n .setProtectedHeader({ alg: 'HS256', typ: 'JWT' })\n .setIssuedAt()\n .setIssuer(this.issuer)\n .setExpirationTime('1d')\n .sign(this.secret);\n }\n\n /**\n * Sign an access token for an authenticated user\n */\n async signAccessToken(\n user: UserInfo,\n scopes: string[],\n audience?: string,\n consentMetadata?: ConsentMetadata,\n ): Promise<string> {\n const claims: Record<string, unknown> = {\n sub: user.sub,\n scope: scopes.join(' '),\n };\n\n if (user.email) claims['email'] = user.email;\n if (user.name) claims['name'] = user.name;\n if (user.picture) claims['picture'] = user.picture;\n if (user.roles) claims['roles'] = user.roles;\n\n // Add consent metadata if present\n if (consentMetadata) {\n if (consentMetadata.consentEnabled) {\n claims['consent'] = {\n enabled: true,\n selectedTools: consentMetadata.selectedToolIds ?? [],\n };\n }\n if (consentMetadata.federatedLoginUsed) {\n claims['federated'] = {\n enabled: true,\n selectedProviders: consentMetadata.selectedProviderIds ?? [],\n skippedProviders: consentMetadata.skippedProviderIds ?? [],\n };\n }\n }\n\n const jwt = new SignJWT(claims)\n .setProtectedHeader({ alg: 'HS256', typ: 'JWT' })\n .setIssuedAt()\n .setIssuer(this.issuer)\n .setExpirationTime(`${this.accessTokenTtlSeconds}s`)\n .setJti(randomUUID());\n\n if (audience) {\n jwt.setAudience(audience);\n }\n\n return jwt.sign(this.secret);\n }\n\n /**\n * Exchange an authorization code for tokens\n */\n async exchangeCode(\n code: string,\n clientId: string,\n redirectUri: string,\n codeVerifier: string,\n ): Promise<TokenResponse | { error: string; error_description: string }> {\n // Get the authorization code record\n const codeRecord = await this.authorizationStore.getAuthorizationCode(code);\n\n if (!codeRecord) {\n this.logger.warn(`Authorization code not found or expired: ${code.substring(0, 8)}...`);\n return {\n error: 'invalid_grant',\n error_description: 'Authorization code is invalid or expired',\n };\n }\n\n // Verify code hasn't been used (single-use)\n if (codeRecord.used) {\n this.logger.warn(`Authorization code already used: ${code.substring(0, 8)}...`);\n // Security: If a code is reused, revoke all tokens from this code\n await this.authorizationStore.deleteAuthorizationCode(code);\n return {\n error: 'invalid_grant',\n error_description: 'Authorization code has already been used',\n };\n }\n\n // Verify client_id matches\n if (codeRecord.clientId !== clientId) {\n this.logger.warn(`Client ID mismatch: expected ${codeRecord.clientId}, got ${clientId}`);\n return {\n error: 'invalid_grant',\n error_description: 'Client ID does not match',\n };\n }\n\n // Verify redirect_uri matches\n if (codeRecord.redirectUri !== redirectUri) {\n this.logger.warn(`Redirect URI mismatch`);\n return {\n error: 'invalid_grant',\n error_description: 'Redirect URI does not match',\n };\n }\n\n // Verify PKCE\n if (!verifyPkce(codeVerifier, codeRecord.pkce)) {\n this.logger.warn(`PKCE verification failed`);\n return {\n error: 'invalid_grant',\n error_description: 'PKCE verification failed',\n };\n }\n\n // Mark code as used\n await this.authorizationStore.markCodeUsed(code);\n\n // Generate tokens\n const user: UserInfo = {\n sub: codeRecord.userSub,\n email: codeRecord.userEmail,\n name: codeRecord.userName,\n };\n\n // Build consent metadata from code record\n const consentMetadata: ConsentMetadata | undefined =\n codeRecord.consentEnabled || codeRecord.federatedLoginUsed\n ? {\n selectedToolIds: codeRecord.selectedToolIds,\n selectedProviderIds: codeRecord.selectedProviderIds,\n skippedProviderIds: codeRecord.skippedProviderIds,\n consentEnabled: codeRecord.consentEnabled,\n federatedLoginUsed: codeRecord.federatedLoginUsed,\n }\n : undefined;\n\n const accessToken = await this.signAccessToken(user, codeRecord.scopes, codeRecord.resource, consentMetadata);\n\n // Create refresh token\n const refreshTokenRecord = this.getInMemoryStore().createRefreshTokenRecord({\n clientId,\n userSub: user.sub,\n scopes: codeRecord.scopes,\n resource: codeRecord.resource,\n });\n await this.authorizationStore.storeRefreshToken(refreshTokenRecord);\n\n this.logger.info(`Tokens issued for user: ${user.sub}`);\n\n return {\n access_token: accessToken,\n token_type: 'Bearer',\n expires_in: this.accessTokenTtlSeconds,\n refresh_token: refreshTokenRecord.token,\n scope: codeRecord.scopes.join(' '),\n };\n }\n\n /**\n * Refresh an access token using a refresh token\n */\n async refreshAccessToken(\n refreshToken: string,\n clientId: string,\n ): Promise<TokenResponse | { error: string; error_description: string }> {\n const tokenRecord = await this.authorizationStore.getRefreshToken(refreshToken);\n\n if (!tokenRecord) {\n this.logger.warn('Refresh token not found or expired');\n return {\n error: 'invalid_grant',\n error_description: 'Refresh token is invalid or expired',\n };\n }\n\n if (tokenRecord.clientId !== clientId) {\n this.logger.warn('Client ID mismatch on refresh');\n return {\n error: 'invalid_grant',\n error_description: 'Client ID does not match',\n };\n }\n\n // Generate new access token\n const user: UserInfo = { sub: tokenRecord.userSub };\n const accessToken = await this.signAccessToken(user, tokenRecord.scopes, tokenRecord.resource);\n\n // Rotate refresh token\n const newRefreshRecord = this.getInMemoryStore().createRefreshTokenRecord({\n clientId,\n userSub: tokenRecord.userSub,\n scopes: tokenRecord.scopes,\n resource: tokenRecord.resource,\n });\n await this.authorizationStore.rotateRefreshToken(refreshToken, newRefreshRecord);\n\n this.logger.info(`Tokens refreshed for user: ${user.sub}`);\n\n return {\n access_token: accessToken,\n token_type: 'Bearer',\n expires_in: this.accessTokenTtlSeconds,\n refresh_token: newRefreshRecord.token,\n scope: tokenRecord.scopes.join(' '),\n };\n }\n\n /**\n * Create an authorization code for a user (called after login)\n */\n async createAuthorizationCode(params: {\n clientId: string;\n redirectUri: string;\n scopes: string[];\n codeChallenge: string;\n userSub: string;\n userEmail?: string;\n userName?: string;\n state?: string;\n resource?: string;\n // Consent and Federated Login Data\n selectedToolIds?: string[];\n selectedProviderIds?: string[];\n skippedProviderIds?: string[];\n consentEnabled?: boolean;\n federatedLoginUsed?: boolean;\n }): Promise<string> {\n const store = this.getInMemoryStore();\n const codeRecord = store.createCodeRecord({\n clientId: params.clientId,\n redirectUri: params.redirectUri,\n scopes: params.scopes,\n pkce: { challenge: params.codeChallenge, method: 'S256' },\n userSub: params.userSub,\n userEmail: params.userEmail,\n userName: params.userName,\n state: params.state,\n resource: params.resource,\n // Consent and Federated Login Data\n selectedToolIds: params.selectedToolIds,\n selectedProviderIds: params.selectedProviderIds,\n skippedProviderIds: params.skippedProviderIds,\n consentEnabled: params.consentEnabled,\n federatedLoginUsed: params.federatedLoginUsed,\n });\n\n await this.authorizationStore.storeAuthorizationCode(codeRecord);\n this.logger.info(`Authorization code created for user: ${params.userSub}`);\n\n return codeRecord.code;\n }\n\n protected async initialize(): Promise<void> {\n // TODO: create separated jwk service for local/remote auth options\n this.providers.injectProvider({\n value: this.jwks,\n metadata: {\n scope: ProviderScope.GLOBAL,\n name: 'auth:jwk-service',\n },\n provide: JwksService,\n });\n\n await this.registerAuthFlows();\n\n return Promise.resolve();\n }\n\n override fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n return fetch(input, init);\n }\n\n override validate(request: ServerRequest): Promise<void> {\n return Promise.resolve();\n }\n\n private async registerAuthFlows() {\n const scope = this.providers.getActiveScope();\n await scope.registryFlows(\n WellKnownPrmFlow /** /.well-known/oauth-protected-resource */,\n WellKnownAsFlow /** /.well-known/oauth-authorization-server */,\n WellKnownJwksFlow /** /.well-known/jwks.json */,\n SessionVerifyFlow /** Session verification flow */,\n\n OauthAuthorizeFlow /** GET /oauth/authorize */,\n OauthTokenFlow /** POST /oauth/token */,\n OauthCallbackFlow /** GET /oauth/callback - login callback */,\n OauthRegisterFlow /** POST /oauth/register */,\n );\n }\n}\n"]}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { FrontMcpAuth,
|
|
1
|
+
import { FrontMcpAuth, ScopeEntry, ServerRequest } from '../../common';
|
|
2
|
+
import { TransparentAuthOptions } from '../../common/types/options/auth.options';
|
|
2
3
|
import { URL } from 'url';
|
|
3
4
|
import ProviderRegistry from '../../provider/provider.registry';
|
|
4
|
-
export declare class RemotePrimaryAuth extends FrontMcpAuth<
|
|
5
|
+
export declare class RemotePrimaryAuth extends FrontMcpAuth<TransparentAuthOptions> {
|
|
5
6
|
private readonly scope;
|
|
6
7
|
private readonly providers;
|
|
7
8
|
ready: Promise<void>;
|
|
8
9
|
private jwks;
|
|
9
|
-
constructor(scope: ScopeEntry, providers: ProviderRegistry, options:
|
|
10
|
+
constructor(scope: ScopeEntry, providers: ProviderRegistry, options: TransparentAuthOptions);
|
|
10
11
|
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
11
12
|
validate(request: ServerRequest): Promise<void>;
|
|
12
13
|
get issuer(): string;
|
|
@@ -26,7 +26,7 @@ class RemotePrimaryAuth extends common_1.FrontMcpAuth {
|
|
|
26
26
|
return Promise.resolve();
|
|
27
27
|
}
|
|
28
28
|
get issuer() {
|
|
29
|
-
return this.options.
|
|
29
|
+
return this.options.remote.provider;
|
|
30
30
|
}
|
|
31
31
|
async initialize() {
|
|
32
32
|
const scope = this.providers.getActiveScope();
|
|
@@ -42,7 +42,7 @@ class RemotePrimaryAuth extends common_1.FrontMcpAuth {
|
|
|
42
42
|
return Promise.resolve();
|
|
43
43
|
}
|
|
44
44
|
async registerAuthFlows(scope) {
|
|
45
|
-
await scope.registryFlows(well_known_prm_flow_1.default
|
|
45
|
+
await scope.registryFlows(well_known_prm_flow_1.default /** /.well-known/oauth-protected-resource */, well_known_oauth_authorization_server_flow_1.default /** /.well-known/oauth-authorization-server */, well_known_jwks_flow_1.default /** /.well-known/jwks.json */, session_verify_flow_1.default /** Session verification flow */);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
exports.RemotePrimaryAuth = RemotePrimaryAuth;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance.remote-primary-auth.js","sourceRoot":"","sources":["../../../../src/auth/instances/instance.remote-primary-auth.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"instance.remote-primary-auth.js","sourceRoot":"","sources":["../../../../src/auth/instances/instance.remote-primary-auth.ts"],"names":[],"mappings":";;;;AAAA,yCAAsF;AAItF,kCAAsC;AACtC,+FAA4D;AAC5D,6IAAkF;AAClF,iGAA8D;AAC9D,+FAA6D;AAG7D,MAAa,iBAAkB,SAAQ,qBAAoC;IAKtD;IACA;IALV,KAAK,CAAgB;IACtB,IAAI,GAAG,IAAI,kBAAW,EAAE,CAAC;IAEjC,YACmB,KAAiB,EACjB,SAA2B,EAC5C,OAA+B;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJE,UAAK,GAAL,KAAK,CAAY;QACjB,cAAS,GAAT,SAAS,CAAkB;QAI5C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;IACjC,CAAC;IAEQ,KAAK,CAAC,KAAwB,EAAE,IAAkB;QACzD,OAAO,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAEQ,QAAQ,CAAC,OAAsB;QACtC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;IACtC,CAAC;IAES,KAAK,CAAC,UAAU;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;QAE9C,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;YAC5B,KAAK,EAAE,IAAI,CAAC,IAAI;YAChB,QAAQ,EAAE;gBACR,KAAK,EAAE,sBAAa,CAAC,MAAM;gBAC3B,IAAI,EAAE,kBAAkB;aACzB;YACD,OAAO,EAAE,kBAAW;SACrB,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACpC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,KAAY;QAC1C,MAAM,KAAK,CAAC,aAAa,CACvB,6BAAgB,CAAC,4CAA4C,EAC7D,oDAAe,CAAC,8CAA8C,EAC9D,8BAAiB,CAAC,6BAA6B,EAC/C,6BAAiB,CAAC,gCAAgC,CACnD,CAAC;IACJ,CAAC;CACF;AAjDD,8CAiDC","sourcesContent":["import { FrontMcpAuth, ProviderScope, ScopeEntry, ServerRequest } from '../../common';\nimport { TransparentAuthOptions } from '../../common/types/options/auth.options';\nimport { URL } from 'url';\nimport ProviderRegistry from '../../provider/provider.registry';\nimport { JwksService } from '../jwks';\nimport WellKnownPrmFlow from '../flows/well-known.prm.flow';\nimport WellKnownAsFlow from '../flows/well-known.oauth-authorization-server.flow';\nimport WellKnownJwksFlow from '../flows/well-known.jwks.flow';\nimport SessionVerifyFlow from '../flows/session.verify.flow';\nimport { Scope } from '../../scope';\n\nexport class RemotePrimaryAuth extends FrontMcpAuth<TransparentAuthOptions> {\n override ready: Promise<void>;\n private jwks = new JwksService();\n\n constructor(\n private readonly scope: ScopeEntry,\n private readonly providers: ProviderRegistry,\n options: TransparentAuthOptions,\n ) {\n super(options);\n this.ready = this.initialize();\n }\n\n override fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n return fetch(input, init);\n }\n\n override validate(request: ServerRequest): Promise<void> {\n return Promise.resolve();\n }\n\n get issuer(): string {\n return this.options.remote.provider;\n }\n\n protected async initialize() {\n const scope = this.providers.getActiveScope();\n\n this.providers.injectProvider({\n value: this.jwks,\n metadata: {\n scope: ProviderScope.GLOBAL,\n name: 'auth:jwk-service',\n },\n provide: JwksService,\n });\n\n await this.registerAuthFlows(scope);\n return Promise.resolve();\n }\n\n private async registerAuthFlows(scope: Scope) {\n await scope.registryFlows(\n WellKnownPrmFlow /** /.well-known/oauth-protected-resource */,\n WellKnownAsFlow /** /.well-known/oauth-authorization-server */,\n WellKnownJwksFlow /** /.well-known/jwks.json */,\n SessionVerifyFlow /** Session verification flow */,\n );\n }\n}\n"]}
|