@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
|
@@ -8,7 +8,7 @@ const tslib_1 = require("tslib");
|
|
|
8
8
|
*
|
|
9
9
|
* When: Start of the flow.
|
|
10
10
|
*
|
|
11
|
-
* Purpose: Authenticate the user and obtain consent; returns an authorization code to the client
|
|
11
|
+
* Purpose: Authenticate the user and obtain consent; returns an authorization code to the client's redirect URI.
|
|
12
12
|
*
|
|
13
13
|
* Notes: Must support PKCE. Implicit/Hybrid are out in OAuth 2.1.
|
|
14
14
|
*/
|
|
@@ -21,6 +21,7 @@ const tslib_1 = require("tslib");
|
|
|
21
21
|
*/
|
|
22
22
|
const common_1 = require("../../common");
|
|
23
23
|
const zod_1 = require("zod");
|
|
24
|
+
const ui_1 = require("../ui");
|
|
24
25
|
/**
|
|
25
26
|
* Quick checklist (security & correctness)
|
|
26
27
|
* - PKCE (S256) required for public clients (and basically for all).
|
|
@@ -33,16 +34,81 @@ const zod_1 = require("zod");
|
|
|
33
34
|
* - Publish discovery and JWKS, rotate keys safely.
|
|
34
35
|
* - Decide JWT vs opaque access tokens; provide introspection if opaque.
|
|
35
36
|
*/
|
|
37
|
+
// ============================================
|
|
38
|
+
// OAuth 2.1 Authorization Request Schemas
|
|
39
|
+
// ============================================
|
|
40
|
+
/**
|
|
41
|
+
* RFC 7636 PKCE: code_challenge is base64url(sha256(code_verifier))
|
|
42
|
+
* Must be 43-128 characters of A-Za-z0-9-._~
|
|
43
|
+
*/
|
|
44
|
+
const pkceChallengeSchema = zod_1.z
|
|
45
|
+
.string()
|
|
46
|
+
.min(43, 'code_challenge must be at least 43 characters')
|
|
47
|
+
.max(128, 'code_challenge must be at most 128 characters')
|
|
48
|
+
.regex(/^[A-Za-z0-9_-]+$/, 'code_challenge must contain only A-Za-z0-9-_');
|
|
49
|
+
/**
|
|
50
|
+
* OAuth 2.1 requires S256 only (plain is deprecated)
|
|
51
|
+
*/
|
|
52
|
+
const codeChallengeMethodSchema = zod_1.z.literal('S256', {
|
|
53
|
+
message: 'code_challenge_method must be "S256" (OAuth 2.1)',
|
|
54
|
+
});
|
|
55
|
+
/**
|
|
56
|
+
* OAuth 2.1 authorization code flow only
|
|
57
|
+
*/
|
|
58
|
+
const responseTypeSchema = zod_1.z.literal('code', {
|
|
59
|
+
message: 'response_type must be "code" (OAuth 2.1)',
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* Validated OAuth authorization request for orchestrated mode
|
|
63
|
+
*/
|
|
64
|
+
const oauthAuthorizeRequestSchema = zod_1.z.object({
|
|
65
|
+
response_type: responseTypeSchema,
|
|
66
|
+
client_id: zod_1.z.string().min(1, 'client_id is required'),
|
|
67
|
+
redirect_uri: zod_1.z.string().url('redirect_uri must be a valid URL'),
|
|
68
|
+
code_challenge: pkceChallengeSchema,
|
|
69
|
+
code_challenge_method: codeChallengeMethodSchema.optional().default('S256'),
|
|
70
|
+
scope: zod_1.z.string().optional(),
|
|
71
|
+
state: zod_1.z.string().optional(),
|
|
72
|
+
resource: zod_1.z.string().url().optional(),
|
|
73
|
+
});
|
|
74
|
+
/**
|
|
75
|
+
* Minimal request for anonymous/default provider mode
|
|
76
|
+
*/
|
|
77
|
+
const anonymousAuthorizeRequestSchema = zod_1.z.object({
|
|
78
|
+
redirect_uri: zod_1.z.string().url('redirect_uri is required'),
|
|
79
|
+
state: zod_1.z.string().optional(),
|
|
80
|
+
});
|
|
81
|
+
// ============================================
|
|
82
|
+
// Flow Schemas
|
|
83
|
+
// ============================================
|
|
36
84
|
const inputSchema = common_1.httpInputSchema;
|
|
37
85
|
const stateSchema = zod_1.z.object({
|
|
38
|
-
isDefaultAuthProvider: zod_1.z.boolean().describe(
|
|
39
|
-
isOrchestrated: zod_1.z.boolean().describe(
|
|
86
|
+
isDefaultAuthProvider: zod_1.z.boolean().describe('If FrontMcp initialized without auth options'),
|
|
87
|
+
isOrchestrated: zod_1.z.boolean().describe('If FrontMcp is orchestrated (local oauth proxy, remote oauth proxy)'),
|
|
40
88
|
allowAnonymous: zod_1.z.boolean().describe('Allow anonymous access, force orchestrated mode'),
|
|
41
|
-
|
|
89
|
+
// Validated OAuth request (after validation)
|
|
90
|
+
validatedRequest: oauthAuthorizeRequestSchema.optional(),
|
|
91
|
+
// Raw parameters for error handling
|
|
92
|
+
rawRedirectUri: zod_1.z.string().optional(),
|
|
93
|
+
rawState: zod_1.z.string().optional(),
|
|
94
|
+
// Validation errors
|
|
95
|
+
validationErrors: zod_1.z.array(zod_1.z.string()).optional(),
|
|
96
|
+
// Pending authorization ID (for login flow)
|
|
97
|
+
pendingAuthId: zod_1.z.string().optional(),
|
|
98
|
+
// Progressive/Incremental Authorization
|
|
99
|
+
isIncrementalAuth: zod_1.z.boolean().default(false).describe('Whether this is an incremental auth request'),
|
|
100
|
+
targetAppId: zod_1.z.string().optional().describe('Target app ID for incremental authorization'),
|
|
101
|
+
targetToolId: zod_1.z.string().optional().describe('Target tool ID that triggered the incremental auth'),
|
|
102
|
+
existingSessionId: zod_1.z.string().optional().describe('Existing session ID for incremental auth'),
|
|
103
|
+
// Federated Login (multi-provider)
|
|
104
|
+
requiresFederatedLogin: zod_1.z.boolean().default(false).describe('Whether this auth requires federated login UI'),
|
|
105
|
+
// Consent Flow
|
|
106
|
+
requiresConsent: zod_1.z.boolean().default(false).describe('Whether consent flow is enabled'),
|
|
42
107
|
});
|
|
43
108
|
const outputSchema = zod_1.z.union([
|
|
44
109
|
common_1.HttpRedirectSchema, // for account/login or oauth/callback
|
|
45
110
|
common_1.HttpTextSchema,
|
|
111
|
+
common_1.HttpHtmlSchema, // for login page
|
|
46
112
|
]);
|
|
47
113
|
const plan = {
|
|
48
114
|
pre: [
|
|
@@ -50,55 +116,657 @@ const plan = {
|
|
|
50
116
|
'validateInput',
|
|
51
117
|
'checkIfAuthorized', // used for direct code generation if refresh-token is provided
|
|
52
118
|
],
|
|
53
|
-
execute: [
|
|
54
|
-
|
|
55
|
-
'buildAuthorizeOutput'
|
|
56
|
-
],
|
|
57
|
-
post: [
|
|
58
|
-
'validateOutput',
|
|
59
|
-
],
|
|
119
|
+
execute: ['prepareAuthorizationRequest', 'buildAuthorizeOutput'],
|
|
120
|
+
post: ['validateOutput'],
|
|
60
121
|
};
|
|
61
122
|
const name = 'oauth:authorize';
|
|
62
123
|
const Stage = (0, common_1.StageHookOf)(name);
|
|
63
124
|
let OauthAuthorizeFlow = class OauthAuthorizeFlow extends common_1.FlowBase {
|
|
125
|
+
logger = this.scope.logger.child('OauthAuthorizeFlow');
|
|
64
126
|
async parseInput() {
|
|
65
127
|
const { metadata } = this.scope;
|
|
66
128
|
const { request } = this.rawInput;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
129
|
+
// Store raw params for error handling (redirect_uri and state needed for error responses)
|
|
130
|
+
const rawRedirectUri = request.query['redirect_uri'];
|
|
131
|
+
const rawState = request.query['state'];
|
|
132
|
+
// Progressive/Incremental Authorization Parameters
|
|
133
|
+
const targetAppId = request.query['app'];
|
|
134
|
+
const targetToolId = request.query['tool'];
|
|
135
|
+
const existingSessionId = request.query['session_id'];
|
|
136
|
+
const mode = request.query['mode'];
|
|
137
|
+
const isIncrementalAuth = mode === 'incremental' || !!targetAppId;
|
|
138
|
+
const isDefaultAuthProvider = !metadata.auth;
|
|
139
|
+
// Check if orchestrated mode with multiple providers (requires federated login)
|
|
140
|
+
// This is determined by checking if there are multiple apps with different auth providers
|
|
141
|
+
let requiresFederatedLogin = false;
|
|
142
|
+
if (metadata.auth && (0, common_1.isOrchestratedMode)(metadata.auth)) {
|
|
143
|
+
// Check if scope has apps with different auth providers
|
|
144
|
+
const apps = this.scope.apps.getApps();
|
|
145
|
+
const appsWithAuth = apps.filter((app) => app.metadata.auth);
|
|
146
|
+
requiresFederatedLogin = appsWithAuth.length > 0;
|
|
147
|
+
}
|
|
148
|
+
// Check if consent flow is enabled
|
|
149
|
+
let requiresConsent = false;
|
|
150
|
+
if (metadata.auth && (0, common_1.isOrchestratedMode)(metadata.auth)) {
|
|
151
|
+
const consentConfig = metadata.auth.consent;
|
|
152
|
+
requiresConsent = consentConfig?.enabled === true;
|
|
153
|
+
}
|
|
154
|
+
this.state.set({
|
|
155
|
+
isOrchestrated: true,
|
|
156
|
+
allowAnonymous: isDefaultAuthProvider,
|
|
157
|
+
isDefaultAuthProvider,
|
|
158
|
+
rawRedirectUri,
|
|
159
|
+
rawState,
|
|
160
|
+
// Progressive/Incremental Authorization
|
|
161
|
+
isIncrementalAuth,
|
|
162
|
+
targetAppId,
|
|
163
|
+
targetToolId,
|
|
164
|
+
existingSessionId,
|
|
165
|
+
// Federated Login
|
|
166
|
+
requiresFederatedLogin,
|
|
167
|
+
// Consent Flow
|
|
168
|
+
requiresConsent,
|
|
169
|
+
});
|
|
170
|
+
if (isIncrementalAuth) {
|
|
171
|
+
this.logger.info(`Incremental authorization requested for app: ${targetAppId}, tool: ${targetToolId}`);
|
|
172
|
+
}
|
|
173
|
+
if (requiresFederatedLogin) {
|
|
174
|
+
this.logger.info(`Federated login required: Multiple auth providers detected`);
|
|
75
175
|
}
|
|
76
|
-
|
|
77
|
-
this.
|
|
176
|
+
if (requiresConsent) {
|
|
177
|
+
this.logger.info(`Consent flow enabled: User will select tools to expose`);
|
|
78
178
|
}
|
|
79
179
|
}
|
|
80
180
|
async validateInput() {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
181
|
+
const { isDefaultAuthProvider, rawRedirectUri, rawState } = this.state;
|
|
182
|
+
const { request } = this.rawInput;
|
|
183
|
+
// Handle default anonymous provider - minimal validation
|
|
184
|
+
if (isDefaultAuthProvider) {
|
|
185
|
+
const result = anonymousAuthorizeRequestSchema.safeParse({
|
|
186
|
+
redirect_uri: rawRedirectUri,
|
|
187
|
+
state: rawState,
|
|
188
|
+
});
|
|
189
|
+
if (!result.success) {
|
|
190
|
+
const errors = this.formatZodErrors(result.error);
|
|
191
|
+
this.logger.warn(`Anonymous authorization request validation failed: ${errors.join(', ')}`);
|
|
192
|
+
this.respond(common_1.httpRespond.html(this.renderErrorPage('invalid_request', errors.join('; ')), 400));
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
// Redirect with anonymous code
|
|
196
|
+
const url = new URL(result.data.redirect_uri);
|
|
197
|
+
url.searchParams.set('code', 'anonymous');
|
|
198
|
+
if (result.data.state) {
|
|
199
|
+
url.searchParams.set('state', result.data.state);
|
|
200
|
+
}
|
|
201
|
+
this.respond(common_1.httpRespond.redirect(url.toString()));
|
|
202
|
+
return;
|
|
84
203
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
204
|
+
// Orchestrated mode - full OAuth 2.1 validation
|
|
205
|
+
const result = oauthAuthorizeRequestSchema.safeParse({
|
|
206
|
+
response_type: request.query['response_type'],
|
|
207
|
+
client_id: request.query['client_id'],
|
|
208
|
+
redirect_uri: rawRedirectUri,
|
|
209
|
+
code_challenge: request.query['code_challenge'],
|
|
210
|
+
code_challenge_method: request.query['code_challenge_method'] ?? 'S256',
|
|
211
|
+
scope: request.query['scope'],
|
|
212
|
+
state: rawState,
|
|
213
|
+
resource: request.query['resource'],
|
|
214
|
+
});
|
|
215
|
+
if (!result.success) {
|
|
216
|
+
const errors = this.formatZodErrors(result.error);
|
|
217
|
+
this.logger.warn(`Authorization request validation failed: ${errors.join(', ')}`);
|
|
218
|
+
this.respondWithError(errors, rawRedirectUri, rawState);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
// Store validated request
|
|
222
|
+
this.state.set('validatedRequest', result.data);
|
|
90
223
|
}
|
|
91
224
|
async checkIfAuthorized() {
|
|
92
|
-
//
|
|
225
|
+
// TODO: Check if user is already authorized (has valid session cookie)
|
|
226
|
+
// If yes, skip login and directly generate authorization code
|
|
227
|
+
// For now, always proceed to login
|
|
93
228
|
}
|
|
94
229
|
async prepareAuthorizationRequest() {
|
|
95
|
-
|
|
230
|
+
const { validatedRequest, isIncrementalAuth, targetAppId, targetToolId, existingSessionId, requiresFederatedLogin, requiresConsent, } = this.state;
|
|
231
|
+
const { metadata } = this.scope;
|
|
232
|
+
if (!validatedRequest) {
|
|
233
|
+
// Should not reach here if validation passed
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
// Store pending authorization request
|
|
237
|
+
const auth = this.scope.auth;
|
|
238
|
+
if (!auth || !('authorizationStore' in auth)) {
|
|
239
|
+
this.respond(common_1.httpRespond.html(this.renderErrorPage('server_error', 'Authorization not configured'), 500));
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const localAuth = auth;
|
|
243
|
+
const store = localAuth.authorizationStore;
|
|
244
|
+
// Build federated login state if multiple providers
|
|
245
|
+
let federatedLogin;
|
|
246
|
+
if (requiresFederatedLogin) {
|
|
247
|
+
// Build provider IDs from apps with auth
|
|
248
|
+
const apps = this.scope.apps.getApps();
|
|
249
|
+
const providerIds = [];
|
|
250
|
+
// Add parent provider
|
|
251
|
+
if (metadata.auth && (0, common_1.isOrchestratedMode)(metadata.auth)) {
|
|
252
|
+
providerIds.push('__parent__');
|
|
253
|
+
}
|
|
254
|
+
// Add app-level providers
|
|
255
|
+
for (const app of apps) {
|
|
256
|
+
if (app.metadata.auth) {
|
|
257
|
+
providerIds.push(app.metadata.id || app.metadata.name);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
federatedLogin = {
|
|
261
|
+
providerIds,
|
|
262
|
+
selectedProviderIds: undefined,
|
|
263
|
+
skippedProviderIds: undefined,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// Build consent state if enabled
|
|
267
|
+
let consent;
|
|
268
|
+
if (requiresConsent) {
|
|
269
|
+
// Get all available tools from the scope
|
|
270
|
+
const tools = this.scope.tools.getTools();
|
|
271
|
+
const availableToolIds = tools.map((t) => t.metadata.id).filter((id) => id !== undefined);
|
|
272
|
+
consent = {
|
|
273
|
+
enabled: true,
|
|
274
|
+
availableToolIds,
|
|
275
|
+
selectedToolIds: undefined,
|
|
276
|
+
consentCompleted: false,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
const pendingRecord = store.createPendingRecord({
|
|
280
|
+
clientId: validatedRequest.client_id,
|
|
281
|
+
redirectUri: validatedRequest.redirect_uri,
|
|
282
|
+
scopes: validatedRequest.scope ? validatedRequest.scope.split(' ') : [],
|
|
283
|
+
pkce: {
|
|
284
|
+
challenge: validatedRequest.code_challenge,
|
|
285
|
+
method: 'S256',
|
|
286
|
+
},
|
|
287
|
+
state: validatedRequest.state,
|
|
288
|
+
resource: validatedRequest.resource,
|
|
289
|
+
// Progressive/Incremental Authorization Fields
|
|
290
|
+
isIncremental: isIncrementalAuth,
|
|
291
|
+
targetAppId,
|
|
292
|
+
targetToolId,
|
|
293
|
+
existingSessionId,
|
|
294
|
+
// Federated Login State
|
|
295
|
+
federatedLogin,
|
|
296
|
+
// Consent State
|
|
297
|
+
consent,
|
|
298
|
+
});
|
|
299
|
+
await localAuth.authorizationStore.storePendingAuthorization(pendingRecord);
|
|
300
|
+
this.logger.info(`Pending authorization created: ${pendingRecord.id}${isIncrementalAuth ? ` (incremental for app: ${targetAppId})` : ''}${requiresFederatedLogin ? ' (federated)' : ''}${requiresConsent ? ' (consent enabled)' : ''}`);
|
|
301
|
+
this.state.set('pendingAuthId', pendingRecord.id);
|
|
96
302
|
}
|
|
97
303
|
async buildAuthorizeOutput() {
|
|
98
|
-
|
|
304
|
+
const { pendingAuthId, validatedRequest, isIncrementalAuth, targetAppId, targetToolId, requiresFederatedLogin } = this.state;
|
|
305
|
+
if (!validatedRequest || !pendingAuthId) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
// For incremental auth, render a single-app authorization page
|
|
309
|
+
if (isIncrementalAuth && targetAppId) {
|
|
310
|
+
const apps = this.scope.apps.getApps();
|
|
311
|
+
const app = apps.find((a) => a.metadata.id === targetAppId);
|
|
312
|
+
const appName = app?.metadata?.name || targetAppId;
|
|
313
|
+
const appDescription = app?.metadata?.description;
|
|
314
|
+
const incrementalAuthHtml = this.renderIncrementalAuthPage({
|
|
315
|
+
pendingAuthId,
|
|
316
|
+
appId: targetAppId,
|
|
317
|
+
appName,
|
|
318
|
+
appDescription,
|
|
319
|
+
toolId: targetToolId,
|
|
320
|
+
redirectUri: validatedRequest.redirect_uri,
|
|
321
|
+
});
|
|
322
|
+
this.respond(common_1.httpRespond.html(incrementalAuthHtml));
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
// For federated login (multiple providers), render provider selection page
|
|
326
|
+
if (requiresFederatedLogin) {
|
|
327
|
+
const apps = this.scope.apps.getApps();
|
|
328
|
+
const providers = [];
|
|
329
|
+
// Add parent provider
|
|
330
|
+
const { metadata } = this.scope;
|
|
331
|
+
if (metadata.auth && (0, common_1.isOrchestratedMode)(metadata.auth)) {
|
|
332
|
+
providers.push({
|
|
333
|
+
id: '__parent__',
|
|
334
|
+
mode: metadata.auth.mode,
|
|
335
|
+
appIds: ['__parent__'],
|
|
336
|
+
scopes: [],
|
|
337
|
+
isParentProvider: true,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
// Add app-level providers
|
|
341
|
+
for (const app of apps) {
|
|
342
|
+
if (app.metadata.auth) {
|
|
343
|
+
providers.push({
|
|
344
|
+
id: app.metadata.id || app.metadata.name,
|
|
345
|
+
providerUrl: app.metadata.auth.mode === 'transparent' ? app.metadata.auth.remote.provider : undefined,
|
|
346
|
+
mode: app.metadata.auth.mode,
|
|
347
|
+
appIds: [app.metadata.id || app.metadata.name],
|
|
348
|
+
scopes: [],
|
|
349
|
+
isParentProvider: false,
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
const detection = {
|
|
354
|
+
providers: new Map(providers.map((p) => [p.id, p])),
|
|
355
|
+
requiresOrchestration: true,
|
|
356
|
+
parentProviderId: '__parent__',
|
|
357
|
+
childProviderIds: providers.filter((p) => !p.isParentProvider).map((p) => p.id),
|
|
358
|
+
uniqueProviderCount: providers.length,
|
|
359
|
+
validationErrors: [],
|
|
360
|
+
warnings: [],
|
|
361
|
+
};
|
|
362
|
+
const federatedLoginHtml = this.renderFederatedLoginPage({
|
|
363
|
+
pendingAuthId,
|
|
364
|
+
detection,
|
|
365
|
+
clientId: validatedRequest.client_id,
|
|
366
|
+
redirectUri: validatedRequest.redirect_uri,
|
|
367
|
+
});
|
|
368
|
+
this.respond(common_1.httpRespond.html(federatedLoginHtml));
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
// Render a simple login page for full authorization
|
|
372
|
+
// In production, this would redirect to a proper login UI
|
|
373
|
+
const loginHtml = this.renderLoginPage({
|
|
374
|
+
pendingAuthId,
|
|
375
|
+
clientId: validatedRequest.client_id,
|
|
376
|
+
scope: validatedRequest.scope ?? '',
|
|
377
|
+
redirectUri: validatedRequest.redirect_uri,
|
|
378
|
+
});
|
|
379
|
+
this.respond(common_1.httpRespond.html(loginHtml));
|
|
99
380
|
}
|
|
100
381
|
async validateOutput() {
|
|
101
|
-
//
|
|
382
|
+
// Output validation is handled by schema
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Format Zod errors into human-readable strings
|
|
386
|
+
*/
|
|
387
|
+
formatZodErrors(error) {
|
|
388
|
+
return error.issues.map((err) => {
|
|
389
|
+
const path = err.path.length > 0 ? `${err.path.join('.')}: ` : '';
|
|
390
|
+
return `${path}${err.message}`;
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Respond with OAuth error - redirect if possible, otherwise show error page
|
|
395
|
+
*/
|
|
396
|
+
respondWithError(errors, redirectUri, state) {
|
|
397
|
+
const errorDescription = errors.join('; ');
|
|
398
|
+
// Try to redirect with error if we have a valid redirect_uri
|
|
399
|
+
if (redirectUri) {
|
|
400
|
+
try {
|
|
401
|
+
const url = new URL(redirectUri);
|
|
402
|
+
url.searchParams.set('error', 'invalid_request');
|
|
403
|
+
url.searchParams.set('error_description', errorDescription);
|
|
404
|
+
if (state) {
|
|
405
|
+
url.searchParams.set('state', state);
|
|
406
|
+
}
|
|
407
|
+
this.respond(common_1.httpRespond.redirect(url.toString()));
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
// Invalid redirect_uri, fall through to error page
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
this.respond(common_1.httpRespond.html(this.renderErrorPage('invalid_request', errorDescription), 400));
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Render a simple login page using HTMX templates
|
|
418
|
+
*/
|
|
419
|
+
renderLoginPage(params) {
|
|
420
|
+
const { pendingAuthId, clientId, scope } = params;
|
|
421
|
+
const callbackPath = `${this.scope.fullPath}/oauth/callback`;
|
|
422
|
+
return (0, ui_1.buildLoginPage)({
|
|
423
|
+
clientName: clientId,
|
|
424
|
+
scope,
|
|
425
|
+
pendingAuthId,
|
|
426
|
+
callbackPath,
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Render incremental authorization page for a single app using HTMX templates
|
|
431
|
+
*/
|
|
432
|
+
renderIncrementalAuthPage(params) {
|
|
433
|
+
const { pendingAuthId, appId, appName, appDescription, toolId } = params;
|
|
434
|
+
const callbackPath = `${this.scope.fullPath}/oauth/callback`;
|
|
435
|
+
const app = {
|
|
436
|
+
appId,
|
|
437
|
+
appName,
|
|
438
|
+
description: appDescription,
|
|
439
|
+
};
|
|
440
|
+
return (0, ui_1.buildIncrementalAuthPage)({
|
|
441
|
+
app,
|
|
442
|
+
toolId: toolId || 'unknown tool',
|
|
443
|
+
sessionHint: pendingAuthId,
|
|
444
|
+
callbackPath,
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Render federated login page for multiple auth providers using HTMX templates
|
|
449
|
+
*/
|
|
450
|
+
renderFederatedLoginPage(params) {
|
|
451
|
+
const { pendingAuthId, detection, clientId } = params;
|
|
452
|
+
const callbackPath = `${this.scope.fullPath}/oauth/callback`;
|
|
453
|
+
// Convert detection providers to ProviderCard format
|
|
454
|
+
const providers = [...detection.providers.values()].map((provider) => ({
|
|
455
|
+
providerId: provider.id,
|
|
456
|
+
providerName: provider.id,
|
|
457
|
+
providerUrl: provider.providerUrl,
|
|
458
|
+
mode: provider.mode,
|
|
459
|
+
appIds: provider.appIds.filter((id) => id !== '__parent__'),
|
|
460
|
+
isPrimary: provider.isParentProvider,
|
|
461
|
+
}));
|
|
462
|
+
return (0, ui_1.buildFederatedLoginPage)({
|
|
463
|
+
providers,
|
|
464
|
+
clientName: clientId,
|
|
465
|
+
pendingAuthId,
|
|
466
|
+
csrfToken: '', // No CSRF needed for GET form
|
|
467
|
+
callbackPath,
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Render consent page for tool selection
|
|
472
|
+
* This is a placeholder - in production, use Juris/Svelte for the UI
|
|
473
|
+
*/
|
|
474
|
+
renderConsentPage(params) {
|
|
475
|
+
const { pendingAuthId, tools, userEmail, userName } = params;
|
|
476
|
+
const callbackPath = `${this.scope.fullPath}/oauth/consent`;
|
|
477
|
+
// Group tools by app
|
|
478
|
+
const toolsByApp = tools.reduce((acc, tool) => {
|
|
479
|
+
if (!acc[tool.appId]) {
|
|
480
|
+
acc[tool.appId] = { appName: tool.appName, tools: [] };
|
|
481
|
+
}
|
|
482
|
+
acc[tool.appId].tools.push(tool);
|
|
483
|
+
return acc;
|
|
484
|
+
}, {});
|
|
485
|
+
// Build tool cards HTML grouped by app
|
|
486
|
+
const appGroupsHtml = Object.entries(toolsByApp)
|
|
487
|
+
.map(([appId, { appName, tools: appTools }]) => {
|
|
488
|
+
const toolCardsHtml = appTools
|
|
489
|
+
.map((tool) => `
|
|
490
|
+
<label class="tool-card">
|
|
491
|
+
<input type="checkbox" name="tools" value="${(0, ui_1.escapeHtml)(tool.id)}" checked>
|
|
492
|
+
<div class="tool-content">
|
|
493
|
+
<div class="tool-name">${(0, ui_1.escapeHtml)(tool.name)}</div>
|
|
494
|
+
${tool.description ? `<div class="tool-description">${(0, ui_1.escapeHtml)(tool.description)}</div>` : ''}
|
|
495
|
+
</div>
|
|
496
|
+
</label>
|
|
497
|
+
`)
|
|
498
|
+
.join('');
|
|
499
|
+
return `
|
|
500
|
+
<div class="app-group">
|
|
501
|
+
<div class="app-group-header">
|
|
502
|
+
<span class="app-group-icon">${(0, ui_1.escapeHtml)(appName.charAt(0).toUpperCase())}</span>
|
|
503
|
+
<span class="app-group-name">${(0, ui_1.escapeHtml)(appName)}</span>
|
|
504
|
+
<button type="button" class="toggle-app" data-app-id="${(0, ui_1.escapeHtml)(appId)}" onclick="toggleAppTools(this.dataset.appId)">Toggle All</button>
|
|
505
|
+
</div>
|
|
506
|
+
<div class="app-tools" data-app="${(0, ui_1.escapeHtml)(appId)}">
|
|
507
|
+
${toolCardsHtml}
|
|
508
|
+
</div>
|
|
509
|
+
</div>
|
|
510
|
+
`;
|
|
511
|
+
})
|
|
512
|
+
.join('');
|
|
513
|
+
return `<!DOCTYPE html>
|
|
514
|
+
<html lang="en">
|
|
515
|
+
<head>
|
|
516
|
+
<meta charset="UTF-8">
|
|
517
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
518
|
+
<title>Select Tools - FrontMCP</title>
|
|
519
|
+
<style>
|
|
520
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
521
|
+
body {
|
|
522
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
523
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
524
|
+
min-height: 100vh;
|
|
525
|
+
display: flex;
|
|
526
|
+
align-items: center;
|
|
527
|
+
justify-content: center;
|
|
528
|
+
padding: 20px;
|
|
529
|
+
}
|
|
530
|
+
.consent-container {
|
|
531
|
+
background: white;
|
|
532
|
+
padding: 40px;
|
|
533
|
+
border-radius: 12px;
|
|
534
|
+
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
|
|
535
|
+
width: 100%;
|
|
536
|
+
max-width: 700px;
|
|
537
|
+
max-height: 90vh;
|
|
538
|
+
overflow-y: auto;
|
|
539
|
+
}
|
|
540
|
+
h1 { color: #333; margin-bottom: 10px; font-size: 24px; }
|
|
541
|
+
.subtitle { color: #666; margin-bottom: 20px; font-size: 14px; line-height: 1.5; }
|
|
542
|
+
.user-info {
|
|
543
|
+
background: #f8f9fa;
|
|
544
|
+
padding: 12px 16px;
|
|
545
|
+
border-radius: 8px;
|
|
546
|
+
margin-bottom: 24px;
|
|
547
|
+
font-size: 14px;
|
|
548
|
+
}
|
|
549
|
+
.user-info strong { color: #333; }
|
|
550
|
+
.select-controls {
|
|
551
|
+
display: flex;
|
|
552
|
+
gap: 16px;
|
|
553
|
+
margin-bottom: 16px;
|
|
554
|
+
align-items: center;
|
|
555
|
+
}
|
|
556
|
+
.select-controls label {
|
|
557
|
+
display: flex;
|
|
558
|
+
align-items: center;
|
|
559
|
+
gap: 8px;
|
|
560
|
+
font-size: 14px;
|
|
561
|
+
color: #666;
|
|
562
|
+
cursor: pointer;
|
|
563
|
+
}
|
|
564
|
+
.app-group {
|
|
565
|
+
background: #f8f9fa;
|
|
566
|
+
border-radius: 12px;
|
|
567
|
+
margin-bottom: 16px;
|
|
568
|
+
overflow: hidden;
|
|
569
|
+
}
|
|
570
|
+
.app-group-header {
|
|
571
|
+
display: flex;
|
|
572
|
+
align-items: center;
|
|
573
|
+
gap: 12px;
|
|
574
|
+
padding: 16px;
|
|
575
|
+
background: #e9ecef;
|
|
576
|
+
}
|
|
577
|
+
.app-group-icon {
|
|
578
|
+
width: 32px;
|
|
579
|
+
height: 32px;
|
|
580
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
581
|
+
border-radius: 8px;
|
|
582
|
+
display: flex;
|
|
583
|
+
align-items: center;
|
|
584
|
+
justify-content: center;
|
|
585
|
+
color: white;
|
|
586
|
+
font-weight: 600;
|
|
587
|
+
}
|
|
588
|
+
.app-group-name { font-weight: 600; color: #333; flex: 1; }
|
|
589
|
+
.toggle-app {
|
|
590
|
+
padding: 6px 12px;
|
|
591
|
+
background: white;
|
|
592
|
+
border: 1px solid #ddd;
|
|
593
|
+
border-radius: 6px;
|
|
594
|
+
font-size: 12px;
|
|
595
|
+
cursor: pointer;
|
|
596
|
+
}
|
|
597
|
+
.toggle-app:hover { background: #f0f0f0; }
|
|
598
|
+
.app-tools { padding: 12px; }
|
|
599
|
+
.tool-card {
|
|
600
|
+
display: flex;
|
|
601
|
+
align-items: flex-start;
|
|
602
|
+
gap: 12px;
|
|
603
|
+
padding: 12px;
|
|
604
|
+
background: white;
|
|
605
|
+
border-radius: 8px;
|
|
606
|
+
margin-bottom: 8px;
|
|
607
|
+
cursor: pointer;
|
|
608
|
+
transition: all 0.2s;
|
|
609
|
+
}
|
|
610
|
+
.tool-card:hover { background: #f0f4ff; }
|
|
611
|
+
.tool-card:last-child { margin-bottom: 0; }
|
|
612
|
+
.tool-card input { margin-top: 2px; }
|
|
613
|
+
.tool-content { flex: 1; }
|
|
614
|
+
.tool-name { font-weight: 500; color: #333; font-size: 14px; }
|
|
615
|
+
.tool-description { font-size: 12px; color: #666; margin-top: 4px; }
|
|
616
|
+
.button-group { display: flex; gap: 12px; margin-top: 24px; }
|
|
617
|
+
button {
|
|
618
|
+
flex: 1;
|
|
619
|
+
padding: 14px;
|
|
620
|
+
border: none;
|
|
621
|
+
border-radius: 8px;
|
|
622
|
+
font-size: 16px;
|
|
623
|
+
font-weight: 600;
|
|
624
|
+
cursor: pointer;
|
|
625
|
+
transition: transform 0.2s, box-shadow 0.2s;
|
|
626
|
+
}
|
|
627
|
+
.btn-confirm {
|
|
628
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
629
|
+
color: white;
|
|
630
|
+
}
|
|
631
|
+
.btn-confirm:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4); }
|
|
632
|
+
.btn-cancel {
|
|
633
|
+
background: #e5e7eb;
|
|
634
|
+
color: #374151;
|
|
635
|
+
}
|
|
636
|
+
.btn-cancel:hover { background: #d1d5db; }
|
|
637
|
+
.selection-summary {
|
|
638
|
+
background: #f0f9ff;
|
|
639
|
+
border: 1px solid #bae6fd;
|
|
640
|
+
border-radius: 8px;
|
|
641
|
+
padding: 12px 16px;
|
|
642
|
+
margin-top: 16px;
|
|
643
|
+
font-size: 13px;
|
|
644
|
+
color: #0369a1;
|
|
645
|
+
}
|
|
646
|
+
</style>
|
|
647
|
+
</head>
|
|
648
|
+
<body>
|
|
649
|
+
<div class="consent-container">
|
|
650
|
+
<h1>Select Tools to Enable</h1>
|
|
651
|
+
<p class="subtitle">
|
|
652
|
+
Choose which tools you want to make available to the AI assistant.
|
|
653
|
+
You can enable or disable tools at any time.
|
|
654
|
+
</p>
|
|
655
|
+
|
|
656
|
+
${userEmail || userName
|
|
657
|
+
? `
|
|
658
|
+
<div class="user-info">
|
|
659
|
+
Logged in as: <strong>${(0, ui_1.escapeHtml)(userName || userEmail || '')}</strong>
|
|
660
|
+
</div>
|
|
661
|
+
`
|
|
662
|
+
: ''}
|
|
663
|
+
|
|
664
|
+
<form action="${(0, ui_1.escapeHtml)(callbackPath)}" method="POST" id="consent-form">
|
|
665
|
+
<input type="hidden" name="pending_auth_id" value="${(0, ui_1.escapeHtml)(pendingAuthId)}">
|
|
666
|
+
|
|
667
|
+
<div class="select-controls">
|
|
668
|
+
<label>
|
|
669
|
+
<input type="checkbox" id="select-all" onchange="toggleAllTools(this)" checked>
|
|
670
|
+
Select all tools
|
|
671
|
+
</label>
|
|
672
|
+
<span style="color: #999; font-size: 12px;" id="selection-count">${tools.length} of ${tools.length} selected</span>
|
|
673
|
+
</div>
|
|
674
|
+
|
|
675
|
+
${appGroupsHtml}
|
|
676
|
+
|
|
677
|
+
<div class="selection-summary" id="selection-summary">
|
|
678
|
+
Selected tools will be available to the AI assistant.
|
|
679
|
+
</div>
|
|
680
|
+
|
|
681
|
+
<div class="button-group">
|
|
682
|
+
<button type="button" class="btn-cancel" onclick="history.back()">Cancel</button>
|
|
683
|
+
<button type="submit" class="btn-confirm">Confirm Selection</button>
|
|
684
|
+
</div>
|
|
685
|
+
</form>
|
|
686
|
+
</div>
|
|
687
|
+
|
|
688
|
+
<script>
|
|
689
|
+
function toggleAllTools(checkbox) {
|
|
690
|
+
const checkboxes = document.querySelectorAll('input[name="tools"]');
|
|
691
|
+
checkboxes.forEach(cb => cb.checked = checkbox.checked);
|
|
692
|
+
updateCount();
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
function toggleAppTools(appId) {
|
|
696
|
+
const container = document.querySelector(\`.app-tools[data-app="\${appId}"]\`);
|
|
697
|
+
const checkboxes = container.querySelectorAll('input[name="tools"]');
|
|
698
|
+
const allChecked = [...checkboxes].every(cb => cb.checked);
|
|
699
|
+
checkboxes.forEach(cb => cb.checked = !allChecked);
|
|
700
|
+
updateSelectAll();
|
|
701
|
+
updateCount();
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
function updateSelectAll() {
|
|
705
|
+
const all = document.querySelectorAll('input[name="tools"]');
|
|
706
|
+
const checked = document.querySelectorAll('input[name="tools"]:checked');
|
|
707
|
+
document.getElementById('select-all').checked = all.length === checked.length;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
function updateCount() {
|
|
711
|
+
const all = document.querySelectorAll('input[name="tools"]');
|
|
712
|
+
const checked = document.querySelectorAll('input[name="tools"]:checked');
|
|
713
|
+
document.getElementById('selection-count').textContent = \`\${checked.length} of \${all.length} selected\`;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
// Add change listeners to all tool checkboxes
|
|
717
|
+
document.querySelectorAll('input[name="tools"]').forEach(cb => {
|
|
718
|
+
cb.addEventListener('change', () => {
|
|
719
|
+
updateSelectAll();
|
|
720
|
+
updateCount();
|
|
721
|
+
});
|
|
722
|
+
});
|
|
723
|
+
</script>
|
|
724
|
+
</body>
|
|
725
|
+
</html>`;
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Render an error page
|
|
729
|
+
*/
|
|
730
|
+
renderErrorPage(error, description) {
|
|
731
|
+
return `<!DOCTYPE html>
|
|
732
|
+
<html lang="en">
|
|
733
|
+
<head>
|
|
734
|
+
<meta charset="UTF-8">
|
|
735
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
736
|
+
<title>Authorization Error</title>
|
|
737
|
+
<style>
|
|
738
|
+
body {
|
|
739
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
740
|
+
background: #f5f5f5;
|
|
741
|
+
min-height: 100vh;
|
|
742
|
+
display: flex;
|
|
743
|
+
align-items: center;
|
|
744
|
+
justify-content: center;
|
|
745
|
+
padding: 20px;
|
|
746
|
+
}
|
|
747
|
+
.error-container {
|
|
748
|
+
background: white;
|
|
749
|
+
padding: 40px;
|
|
750
|
+
border-radius: 12px;
|
|
751
|
+
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
|
|
752
|
+
max-width: 500px;
|
|
753
|
+
text-align: center;
|
|
754
|
+
}
|
|
755
|
+
.error-icon { font-size: 48px; margin-bottom: 20px; }
|
|
756
|
+
h1 { color: #e53e3e; margin-bottom: 10px; }
|
|
757
|
+
p { color: #666; line-height: 1.6; }
|
|
758
|
+
.error-code { font-family: monospace; background: #f5f5f5; padding: 4px 8px; border-radius: 4px; }
|
|
759
|
+
</style>
|
|
760
|
+
</head>
|
|
761
|
+
<body>
|
|
762
|
+
<div class="error-container">
|
|
763
|
+
<div class="error-icon">⚠️</div>
|
|
764
|
+
<h1>Authorization Error</h1>
|
|
765
|
+
<p><span class="error-code">${(0, ui_1.escapeHtml)(error)}</span></p>
|
|
766
|
+
<p>${(0, ui_1.escapeHtml)(description)}</p>
|
|
767
|
+
</div>
|
|
768
|
+
</body>
|
|
769
|
+
</html>`;
|
|
102
770
|
}
|
|
103
771
|
};
|
|
104
772
|
tslib_1.__decorate([
|