@rekog/mcp-nest 1.9.10 → 2.0.0-alpha.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 +76 -29
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/decorators/constants.d.ts +1 -0
- package/dist/mcp/decorators/constants.d.ts.map +1 -1
- package/dist/mcp/decorators/constants.js +2 -1
- package/dist/mcp/decorators/constants.js.map +1 -1
- package/dist/mcp/decorators/index.d.ts +3 -1
- package/dist/mcp/decorators/index.d.ts.map +1 -1
- package/dist/mcp/decorators/index.js +3 -1
- package/dist/mcp/decorators/index.js.map +1 -1
- package/dist/mcp/decorators/mcp-controller.decorator.d.ts +6 -0
- package/dist/mcp/decorators/mcp-controller.decorator.d.ts.map +1 -0
- package/dist/mcp/decorators/mcp-controller.decorator.js +43 -0
- package/dist/mcp/decorators/mcp-controller.decorator.js.map +1 -0
- package/dist/mcp/decorators/mcp-message-pattern.d.ts +3 -0
- package/dist/mcp/decorators/mcp-message-pattern.d.ts.map +1 -0
- package/dist/mcp/decorators/mcp-message-pattern.js +13 -0
- package/dist/mcp/decorators/mcp-message-pattern.js.map +1 -0
- package/dist/mcp/decorators/prompt.decorator.d.ts +1 -1
- package/dist/mcp/decorators/prompt.decorator.d.ts.map +1 -1
- package/dist/mcp/decorators/prompt.decorator.js +2 -1
- package/dist/mcp/decorators/prompt.decorator.js.map +1 -1
- package/dist/mcp/decorators/public.decorator.js.map +1 -1
- package/dist/mcp/decorators/raw-request.decorator.d.ts +2 -0
- package/dist/mcp/decorators/raw-request.decorator.d.ts.map +1 -0
- package/dist/mcp/decorators/raw-request.decorator.js +6 -0
- package/dist/mcp/decorators/raw-request.decorator.js.map +1 -0
- package/dist/mcp/decorators/resource-template.decorator.d.ts +1 -1
- package/dist/mcp/decorators/resource-template.decorator.d.ts.map +1 -1
- package/dist/mcp/decorators/resource-template.decorator.js +2 -1
- package/dist/mcp/decorators/resource-template.decorator.js.map +1 -1
- package/dist/mcp/decorators/resource.decorator.d.ts +1 -1
- package/dist/mcp/decorators/resource.decorator.d.ts.map +1 -1
- package/dist/mcp/decorators/resource.decorator.js +2 -1
- package/dist/mcp/decorators/resource.decorator.js.map +1 -1
- package/dist/mcp/decorators/tool.decorator.d.ts +1 -3
- package/dist/mcp/decorators/tool.decorator.d.ts.map +1 -1
- package/dist/mcp/decorators/tool.decorator.js +2 -1
- package/dist/mcp/decorators/tool.decorator.js.map +1 -1
- package/dist/mcp/filters/mcp-exception.filter.d.ts +6 -0
- package/dist/mcp/filters/mcp-exception.filter.d.ts.map +1 -0
- package/dist/mcp/filters/mcp-exception.filter.js +26 -0
- package/dist/mcp/filters/mcp-exception.filter.js.map +1 -0
- package/dist/mcp/index.d.ts +11 -7
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +11 -7
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/interfaces/authenticated-user.interface.d.ts +9 -0
- package/dist/mcp/interfaces/authenticated-user.interface.d.ts.map +1 -0
- package/dist/{authz/interfaces/request-with-user.js → mcp/interfaces/authenticated-user.interface.js} +1 -1
- package/dist/mcp/interfaces/authenticated-user.interface.js.map +1 -0
- package/dist/mcp/interfaces/dynamic-prompt.interface.d.ts +1 -1
- package/dist/mcp/interfaces/dynamic-prompt.interface.d.ts.map +1 -1
- package/dist/mcp/interfaces/dynamic-prompt.interface.js.map +1 -1
- package/dist/mcp/interfaces/dynamic-resource.interface.d.ts +1 -1
- package/dist/mcp/interfaces/dynamic-resource.interface.d.ts.map +1 -1
- package/dist/mcp/interfaces/dynamic-resource.interface.js.map +1 -1
- package/dist/mcp/interfaces/dynamic-tool.interface.d.ts +1 -1
- package/dist/mcp/interfaces/dynamic-tool.interface.d.ts.map +1 -1
- package/dist/mcp/interfaces/dynamic-tool.interface.js.map +1 -1
- package/dist/mcp/interfaces/index.d.ts +2 -2
- package/dist/mcp/interfaces/index.d.ts.map +1 -1
- package/dist/mcp/interfaces/index.js +0 -3
- package/dist/mcp/interfaces/index.js.map +1 -1
- package/dist/mcp/services/tool-authorization.service.d.ts +7 -5
- package/dist/mcp/services/tool-authorization.service.d.ts.map +1 -1
- package/dist/mcp/services/tool-authorization.service.js +9 -6
- package/dist/mcp/services/tool-authorization.service.js.map +1 -1
- package/dist/mcp/transport/mcp-context.d.ts +34 -0
- package/dist/mcp/transport/mcp-context.d.ts.map +1 -0
- package/dist/mcp/transport/mcp-context.js +74 -0
- package/dist/mcp/transport/mcp-context.js.map +1 -0
- package/dist/mcp/transport/mcp-http-handler.d.ts +7 -0
- package/dist/mcp/transport/mcp-http-handler.d.ts.map +1 -0
- package/dist/mcp/transport/mcp-http-handler.js +5 -0
- package/dist/mcp/transport/mcp-http-handler.js.map +1 -0
- package/dist/mcp/transport/mcp-server-options.interface.d.ts +23 -0
- package/dist/mcp/transport/mcp-server-options.interface.d.ts.map +1 -0
- package/dist/{authz/providers/oauth-provider.interface.js → mcp/transport/mcp-server-options.interface.js} +1 -1
- package/dist/mcp/transport/mcp-server-options.interface.js.map +1 -0
- package/dist/mcp/transport/mcp-transport.constants.d.ts +19 -0
- package/dist/mcp/transport/mcp-transport.constants.d.ts.map +1 -0
- package/dist/mcp/transport/mcp-transport.constants.js +21 -0
- package/dist/mcp/transport/mcp-transport.constants.js.map +1 -0
- package/dist/mcp/transport/mcp-transport.interface.d.ts +17 -0
- package/dist/mcp/transport/mcp-transport.interface.d.ts.map +1 -0
- package/dist/{authz/interfaces/oauth-common.interface.js → mcp/transport/mcp-transport.interface.js} +1 -1
- package/dist/mcp/transport/mcp-transport.interface.js.map +1 -0
- package/dist/mcp/transport/mcp.strategy.d.ts +56 -0
- package/dist/mcp/transport/mcp.strategy.d.ts.map +1 -0
- package/dist/mcp/transport/mcp.strategy.js +446 -0
- package/dist/mcp/transport/mcp.strategy.js.map +1 -0
- package/dist/mcp/transport/resource-matcher.d.ts +13 -0
- package/dist/mcp/transport/resource-matcher.d.ts.map +1 -0
- package/dist/mcp/transport/resource-matcher.js +83 -0
- package/dist/mcp/transport/resource-matcher.js.map +1 -0
- package/dist/mcp/transport/streamable-http.controller.d.ts +16 -0
- package/dist/mcp/transport/streamable-http.controller.d.ts.map +1 -0
- package/dist/mcp/transport/streamable-http.controller.js +98 -0
- package/dist/mcp/transport/streamable-http.controller.js.map +1 -0
- package/dist/mcp/transport/transports/index.d.ts +3 -0
- package/dist/mcp/transport/transports/index.d.ts.map +1 -0
- package/dist/{authz → mcp/transport/transports}/index.js +2 -10
- package/dist/mcp/transport/transports/index.js.map +1 -0
- package/dist/mcp/transport/transports/read-body.d.ts +3 -0
- package/dist/mcp/transport/transports/read-body.d.ts.map +1 -0
- package/dist/mcp/transport/transports/read-body.js +32 -0
- package/dist/mcp/transport/transports/read-body.js.map +1 -0
- package/dist/mcp/transport/transports/stdio.transport.d.ts +9 -0
- package/dist/mcp/transport/transports/stdio.transport.d.ts.map +1 -0
- package/dist/mcp/transport/transports/stdio.transport.js +27 -0
- package/dist/mcp/transport/transports/stdio.transport.js.map +1 -0
- package/dist/mcp/transport/transports/streamable-http.transport.d.ts +33 -0
- package/dist/mcp/transport/transports/streamable-http.transport.d.ts.map +1 -0
- package/dist/mcp/transport/transports/streamable-http.transport.js +216 -0
- package/dist/mcp/transport/transports/streamable-http.transport.js.map +1 -0
- package/dist/mcp/utils/mcp-logger.factory.d.ts +6 -2
- package/dist/mcp/utils/mcp-logger.factory.d.ts.map +1 -1
- package/dist/mcp/utils/mcp-logger.factory.js.map +1 -1
- package/package.json +3 -66
- package/src/index.ts +0 -1
- package/src/mcp/decorators/constants.ts +1 -0
- package/src/mcp/decorators/index.ts +3 -1
- package/src/mcp/decorators/mcp-controller.decorator.ts +126 -0
- package/src/mcp/decorators/mcp-message-pattern.ts +38 -0
- package/src/mcp/decorators/prompt.decorator.ts +6 -2
- package/src/mcp/decorators/public.decorator.ts +3 -3
- package/src/mcp/decorators/raw-request.decorator.ts +32 -0
- package/src/mcp/decorators/resource-template.decorator.ts +6 -2
- package/src/mcp/decorators/resource.decorator.ts +6 -2
- package/src/mcp/decorators/tool.decorator.ts +6 -3
- package/src/mcp/filters/mcp-exception.filter.ts +47 -0
- package/src/mcp/index.ts +13 -7
- package/src/mcp/interfaces/authenticated-user.interface.ts +22 -0
- package/src/mcp/interfaces/dynamic-prompt.interface.ts +1 -1
- package/src/mcp/interfaces/dynamic-resource.interface.ts +1 -1
- package/src/mcp/interfaces/dynamic-tool.interface.ts +2 -2
- package/src/mcp/interfaces/index.ts +3 -7
- package/src/mcp/services/tool-authorization.service.ts +52 -72
- package/src/mcp/transport/mcp-context.ts +138 -0
- package/src/mcp/transport/mcp-http-handler.ts +32 -0
- package/src/mcp/transport/mcp-server-options.interface.ts +75 -0
- package/src/mcp/transport/mcp-transport.constants.ts +99 -0
- package/src/mcp/transport/mcp-transport.interface.ts +50 -0
- package/src/mcp/transport/mcp.strategy.ts +752 -0
- package/src/mcp/transport/resource-matcher.ts +107 -0
- package/src/mcp/transport/streamable-http.controller.ts +114 -0
- package/src/mcp/transport/transports/index.ts +2 -0
- package/src/mcp/transport/transports/read-body.ts +39 -0
- package/src/mcp/transport/transports/stdio.transport.ts +35 -0
- package/src/mcp/transport/transports/streamable-http.transport.ts +384 -0
- package/src/mcp/utils/mcp-logger.factory.spec.ts +8 -22
- package/src/mcp/utils/mcp-logger.factory.ts +13 -2
- package/dist/authz/guards/jwt-auth.guard.d.ts +0 -19
- package/dist/authz/guards/jwt-auth.guard.d.ts.map +0 -1
- package/dist/authz/guards/jwt-auth.guard.js +0 -108
- package/dist/authz/guards/jwt-auth.guard.js.map +0 -1
- package/dist/authz/index.d.ts +0 -11
- package/dist/authz/index.d.ts.map +0 -1
- package/dist/authz/index.js.map +0 -1
- package/dist/authz/interfaces/oauth-common.interface.d.ts +0 -21
- package/dist/authz/interfaces/oauth-common.interface.d.ts.map +0 -1
- package/dist/authz/interfaces/oauth-common.interface.js.map +0 -1
- package/dist/authz/interfaces/request-with-user.d.ts +0 -13
- package/dist/authz/interfaces/request-with-user.d.ts.map +0 -1
- package/dist/authz/interfaces/request-with-user.js.map +0 -1
- package/dist/authz/mcp-oauth.controller.d.ts +0 -81
- package/dist/authz/mcp-oauth.controller.d.ts.map +0 -1
- package/dist/authz/mcp-oauth.controller.js +0 -540
- package/dist/authz/mcp-oauth.controller.js.map +0 -1
- package/dist/authz/mcp-oauth.module.d.ts +0 -12
- package/dist/authz/mcp-oauth.module.d.ts.map +0 -1
- package/dist/authz/mcp-oauth.module.js +0 -271
- package/dist/authz/mcp-oauth.module.js.map +0 -1
- package/dist/authz/providers/azure-ad.provider.d.ts +0 -3
- package/dist/authz/providers/azure-ad.provider.d.ts.map +0 -1
- package/dist/authz/providers/azure-ad.provider.js +0 -37
- package/dist/authz/providers/azure-ad.provider.js.map +0 -1
- package/dist/authz/providers/github.provider.d.ts +0 -3
- package/dist/authz/providers/github.provider.d.ts.map +0 -1
- package/dist/authz/providers/github.provider.js +0 -24
- package/dist/authz/providers/github.provider.js.map +0 -1
- package/dist/authz/providers/google.provider.d.ts +0 -3
- package/dist/authz/providers/google.provider.d.ts.map +0 -1
- package/dist/authz/providers/google.provider.js +0 -25
- package/dist/authz/providers/google.provider.js.map +0 -1
- package/dist/authz/providers/oauth-provider.interface.d.ts +0 -107
- package/dist/authz/providers/oauth-provider.interface.d.ts.map +0 -1
- package/dist/authz/providers/oauth-provider.interface.js.map +0 -1
- package/dist/authz/services/client.service.d.ts +0 -12
- package/dist/authz/services/client.service.d.ts.map +0 -1
- package/dist/authz/services/client.service.js +0 -81
- package/dist/authz/services/client.service.js.map +0 -1
- package/dist/authz/services/jwt-token.service.d.ts +0 -37
- package/dist/authz/services/jwt-token.service.d.ts.map +0 -1
- package/dist/authz/services/jwt-token.service.js +0 -182
- package/dist/authz/services/jwt-token.service.js.map +0 -1
- package/dist/authz/services/oauth-strategy.service.d.ts +0 -13
- package/dist/authz/services/oauth-strategy.service.d.ts.map +0 -1
- package/dist/authz/services/oauth-strategy.service.js +0 -71
- package/dist/authz/services/oauth-strategy.service.js.map +0 -1
- package/dist/authz/stores/memory-store.service.d.ts +0 -27
- package/dist/authz/stores/memory-store.service.d.ts.map +0 -1
- package/dist/authz/stores/memory-store.service.js +0 -107
- package/dist/authz/stores/memory-store.service.js.map +0 -1
- package/dist/authz/stores/oauth-store.interface.d.ts +0 -61
- package/dist/authz/stores/oauth-store.interface.d.ts.map +0 -1
- package/dist/authz/stores/oauth-store.interface.js +0 -5
- package/dist/authz/stores/oauth-store.interface.js.map +0 -1
- package/dist/authz/stores/typeorm/constants.d.ts +0 -3
- package/dist/authz/stores/typeorm/constants.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/constants.js +0 -6
- package/dist/authz/stores/typeorm/constants.js.map +0 -1
- package/dist/authz/stores/typeorm/entities/authorization-code.entity.d.ts +0 -15
- package/dist/authz/stores/typeorm/entities/authorization-code.entity.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/entities/authorization-code.entity.js +0 -69
- package/dist/authz/stores/typeorm/entities/authorization-code.entity.js.map +0 -1
- package/dist/authz/stores/typeorm/entities/index.d.ts +0 -5
- package/dist/authz/stores/typeorm/entities/index.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/entities/index.js +0 -12
- package/dist/authz/stores/typeorm/entities/index.js.map +0 -1
- package/dist/authz/stores/typeorm/entities/oauth-client.entity.d.ts +0 -17
- package/dist/authz/stores/typeorm/entities/oauth-client.entity.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/entities/oauth-client.entity.js +0 -77
- package/dist/authz/stores/typeorm/entities/oauth-client.entity.js.map +0 -1
- package/dist/authz/stores/typeorm/entities/oauth-session.entity.d.ts +0 -14
- package/dist/authz/stores/typeorm/entities/oauth-session.entity.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/entities/oauth-session.entity.js +0 -65
- package/dist/authz/stores/typeorm/entities/oauth-session.entity.js.map +0 -1
- package/dist/authz/stores/typeorm/entities/user-profile.entity.d.ts +0 -13
- package/dist/authz/stores/typeorm/entities/user-profile.entity.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/entities/user-profile.entity.js +0 -62
- package/dist/authz/stores/typeorm/entities/user-profile.entity.js.map +0 -1
- package/dist/authz/stores/typeorm/typeorm-store.service.d.ts +0 -28
- package/dist/authz/stores/typeorm/typeorm-store.service.d.ts.map +0 -1
- package/dist/authz/stores/typeorm/typeorm-store.service.js +0 -138
- package/dist/authz/stores/typeorm/typeorm-store.service.js.map +0 -1
- package/dist/mcp/constants/feature-registration.constants.d.ts +0 -7
- package/dist/mcp/constants/feature-registration.constants.d.ts.map +0 -1
- package/dist/mcp/constants/feature-registration.constants.js +0 -5
- package/dist/mcp/constants/feature-registration.constants.js.map +0 -1
- package/dist/mcp/decorators/tool-guards.decorator.d.ts +0 -12
- package/dist/mcp/decorators/tool-guards.decorator.d.ts.map +0 -1
- package/dist/mcp/decorators/tool-guards.decorator.js +0 -13
- package/dist/mcp/decorators/tool-guards.decorator.js.map +0 -1
- package/dist/mcp/interfaces/mcp-options.interface.d.ts +0 -53
- package/dist/mcp/interfaces/mcp-options.interface.d.ts.map +0 -1
- package/dist/mcp/interfaces/mcp-options.interface.js +0 -10
- package/dist/mcp/interfaces/mcp-options.interface.js.map +0 -1
- package/dist/mcp/mcp.module.d.ts +0 -15
- package/dist/mcp/mcp.module.d.ts.map +0 -1
- package/dist/mcp/mcp.module.js +0 -248
- package/dist/mcp/mcp.module.js.map +0 -1
- package/dist/mcp/services/handlers/mcp-handler.base.d.ts +0 -117
- package/dist/mcp/services/handlers/mcp-handler.base.d.ts.map +0 -1
- package/dist/mcp/services/handlers/mcp-handler.base.js +0 -125
- package/dist/mcp/services/handlers/mcp-handler.base.js.map +0 -1
- package/dist/mcp/services/handlers/mcp-prompts.handler.d.ts +0 -12
- package/dist/mcp/services/handlers/mcp-prompts.handler.d.ts.map +0 -1
- package/dist/mcp/services/handlers/mcp-prompts.handler.js +0 -98
- package/dist/mcp/services/handlers/mcp-prompts.handler.js.map +0 -1
- package/dist/mcp/services/handlers/mcp-resources.handler.d.ts +0 -13
- package/dist/mcp/services/handlers/mcp-resources.handler.d.ts.map +0 -1
- package/dist/mcp/services/handlers/mcp-resources.handler.js +0 -117
- package/dist/mcp/services/handlers/mcp-resources.handler.js.map +0 -1
- package/dist/mcp/services/handlers/mcp-tools.handler.d.ts +0 -22
- package/dist/mcp/services/handlers/mcp-tools.handler.d.ts.map +0 -1
- package/dist/mcp/services/handlers/mcp-tools.handler.js +0 -258
- package/dist/mcp/services/handlers/mcp-tools.handler.js.map +0 -1
- package/dist/mcp/services/mcp-dynamic-registry.service.d.ts +0 -26
- package/dist/mcp/services/mcp-dynamic-registry.service.d.ts.map +0 -1
- package/dist/mcp/services/mcp-dynamic-registry.service.js +0 -133
- package/dist/mcp/services/mcp-dynamic-registry.service.js.map +0 -1
- package/dist/mcp/services/mcp-executor.service.d.ts +0 -15
- package/dist/mcp/services/mcp-executor.service.d.ts.map +0 -1
- package/dist/mcp/services/mcp-executor.service.js +0 -47
- package/dist/mcp/services/mcp-executor.service.js.map +0 -1
- package/dist/mcp/services/mcp-registry-discovery.service.d.ts +0 -63
- package/dist/mcp/services/mcp-registry-discovery.service.d.ts.map +0 -1
- package/dist/mcp/services/mcp-registry-discovery.service.js +0 -397
- package/dist/mcp/services/mcp-registry-discovery.service.js.map +0 -1
- package/dist/mcp/services/mcp-sse.service.d.ts +0 -20
- package/dist/mcp/services/mcp-sse.service.d.ts.map +0 -1
- package/dist/mcp/services/mcp-sse.service.js +0 -91
- package/dist/mcp/services/mcp-sse.service.js.map +0 -1
- package/dist/mcp/services/mcp-streamable-http.service.d.ts +0 -32
- package/dist/mcp/services/mcp-streamable-http.service.d.ts.map +0 -1
- package/dist/mcp/services/mcp-streamable-http.service.js +0 -327
- package/dist/mcp/services/mcp-streamable-http.service.js.map +0 -1
- package/dist/mcp/services/sse-ping.service.d.ts +0 -23
- package/dist/mcp/services/sse-ping.service.d.ts.map +0 -1
- package/dist/mcp/services/sse-ping.service.js +0 -99
- package/dist/mcp/services/sse-ping.service.js.map +0 -1
- package/dist/mcp/transport/sse.controller.factory.d.ts +0 -14
- package/dist/mcp/transport/sse.controller.factory.d.ts.map +0 -1
- package/dist/mcp/transport/sse.controller.factory.js +0 -67
- package/dist/mcp/transport/sse.controller.factory.js.map +0 -1
- package/dist/mcp/transport/stdio.service.d.ts +0 -14
- package/dist/mcp/transport/stdio.service.d.ts.map +0 -1
- package/dist/mcp/transport/stdio.service.js +0 -66
- package/dist/mcp/transport/stdio.service.js.map +0 -1
- package/dist/mcp/transport/streamable-http.controller.factory.d.ts +0 -14
- package/dist/mcp/transport/streamable-http.controller.factory.d.ts.map +0 -1
- package/dist/mcp/transport/streamable-http.controller.factory.js +0 -74
- package/dist/mcp/transport/streamable-http.controller.factory.js.map +0 -1
- package/dist/mcp/utils/capabilities-builder.d.ts +0 -5
- package/dist/mcp/utils/capabilities-builder.d.ts.map +0 -1
- package/dist/mcp/utils/capabilities-builder.js +0 -25
- package/dist/mcp/utils/capabilities-builder.js.map +0 -1
- package/dist/mcp/utils/mcp-server.factory.d.ts +0 -6
- package/dist/mcp/utils/mcp-server.factory.d.ts.map +0 -1
- package/dist/mcp/utils/mcp-server.factory.js +0 -22
- package/dist/mcp/utils/mcp-server.factory.js.map +0 -1
- package/src/authz/guards/jwt-auth.guard.ts +0 -127
- package/src/authz/index.ts +0 -10
- package/src/authz/interfaces/oauth-common.interface.ts +0 -21
- package/src/authz/interfaces/request-with-user.ts +0 -16
- package/src/authz/mcp-oauth.controller.ts +0 -860
- package/src/authz/mcp-oauth.module.ts +0 -384
- package/src/authz/providers/azure-ad.provider.ts +0 -40
- package/src/authz/providers/github.provider.ts +0 -22
- package/src/authz/providers/google.provider.ts +0 -23
- package/src/authz/providers/oauth-provider.interface.ts +0 -147
- package/src/authz/services/client.service.ts +0 -125
- package/src/authz/services/jwt-token.service.spec.ts +0 -67
- package/src/authz/services/jwt-token.service.ts +0 -188
- package/src/authz/services/oauth-strategy.service.ts +0 -64
- package/src/authz/stores/memory-store.service.spec.ts +0 -475
- package/src/authz/stores/memory-store.service.ts +0 -141
- package/src/authz/stores/oauth-store.interface.ts +0 -131
- package/src/authz/stores/typeorm/README.md +0 -140
- package/src/authz/stores/typeorm/constants.ts +0 -6
- package/src/authz/stores/typeorm/entities/authorization-code.entity.ts +0 -41
- package/src/authz/stores/typeorm/entities/index.ts +0 -4
- package/src/authz/stores/typeorm/entities/oauth-client.entity.ts +0 -53
- package/src/authz/stores/typeorm/entities/oauth-session.entity.ts +0 -38
- package/src/authz/stores/typeorm/entities/user-profile.entity.ts +0 -46
- package/src/authz/stores/typeorm/typeorm-store.service.spec.ts +0 -494
- package/src/authz/stores/typeorm/typeorm-store.service.ts +0 -165
- package/src/mcp/constants/feature-registration.constants.ts +0 -24
- package/src/mcp/decorators/tool-guards.decorator.ts +0 -82
- package/src/mcp/interfaces/mcp-options.interface.ts +0 -95
- package/src/mcp/mcp.module.ts +0 -349
- package/src/mcp/services/handlers/mcp-handler.base.ts +0 -203
- package/src/mcp/services/handlers/mcp-prompts.handler.ts +0 -143
- package/src/mcp/services/handlers/mcp-resources.handler.ts +0 -183
- package/src/mcp/services/handlers/mcp-tools.handler.spec.ts +0 -41
- package/src/mcp/services/handlers/mcp-tools.handler.ts +0 -436
- package/src/mcp/services/mcp-dynamic-registry.service.ts +0 -236
- package/src/mcp/services/mcp-executor.service.ts +0 -64
- package/src/mcp/services/mcp-registry-discovery.service.spec.ts +0 -306
- package/src/mcp/services/mcp-registry-discovery.service.ts +0 -849
- package/src/mcp/services/mcp-sse.service.ts +0 -124
- package/src/mcp/services/mcp-streamable-http.service.ts +0 -472
- package/src/mcp/services/sse-ping.service.ts +0 -144
- package/src/mcp/transport/custom-decorator.spec.ts +0 -75
- package/src/mcp/transport/sse.controller.factory.ts +0 -84
- package/src/mcp/transport/stdio.service.ts +0 -75
- package/src/mcp/transport/streamable-http.controller.factory.ts +0 -80
- package/src/mcp/utils/capabilities-builder.ts +0 -43
- package/src/mcp/utils/mcp-server.factory.ts +0 -33
|
@@ -1,475 +0,0 @@
|
|
|
1
|
-
import { Test, TestingModule } from '@nestjs/testing';
|
|
2
|
-
import { MemoryStore } from './memory-store.service';
|
|
3
|
-
import { OAuthClient, AuthorizationCode } from './oauth-store.interface';
|
|
4
|
-
import { OAuthSession } from '../providers/oauth-provider.interface';
|
|
5
|
-
|
|
6
|
-
describe('MemoryStore', () => {
|
|
7
|
-
let service: MemoryStore;
|
|
8
|
-
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
const module: TestingModule = await Test.createTestingModule({
|
|
11
|
-
providers: [MemoryStore],
|
|
12
|
-
}).compile();
|
|
13
|
-
|
|
14
|
-
service = module.get<MemoryStore>(MemoryStore);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('should be defined', () => {
|
|
18
|
-
expect(service).toBeDefined();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
describe('generateClientId', () => {
|
|
22
|
-
it('should generate consistent client IDs for identical objects', () => {
|
|
23
|
-
const client1: Partial<OAuthClient> = {
|
|
24
|
-
client_name: 'MCP Inspector',
|
|
25
|
-
client_uri: 'https://github.com/modelcontextprotocol/inspector',
|
|
26
|
-
redirect_uris: ['http://localhost:6274/oauth/callback'],
|
|
27
|
-
token_endpoint_auth_method: 'none',
|
|
28
|
-
grant_types: ['authorization_code', 'refresh_token'],
|
|
29
|
-
response_types: ['code'],
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const client2: Partial<OAuthClient> = {
|
|
33
|
-
client_name: 'MCP Inspector',
|
|
34
|
-
client_uri: 'https://github.com/modelcontextprotocol/inspector',
|
|
35
|
-
redirect_uris: ['http://localhost:6274/oauth/callback'],
|
|
36
|
-
token_endpoint_auth_method: 'none',
|
|
37
|
-
grant_types: ['authorization_code', 'refresh_token'],
|
|
38
|
-
response_types: ['code'],
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const id1 = service.generateClientId(client1 as OAuthClient);
|
|
42
|
-
const id2 = service.generateClientId(client2 as OAuthClient);
|
|
43
|
-
|
|
44
|
-
expect(id1).toBe(id2);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('should generate consistent client IDs regardless of property order', () => {
|
|
48
|
-
// First object with properties in one order
|
|
49
|
-
const clientJson1 = `{
|
|
50
|
-
"client_name": "MCP Inspector",
|
|
51
|
-
"client_uri": "https://github.com/modelcontextprotocol/inspector",
|
|
52
|
-
"redirect_uris": ["http://localhost:6274/oauth/callback"],
|
|
53
|
-
"token_endpoint_auth_method": "none",
|
|
54
|
-
"grant_types": ["authorization_code", "refresh_token"],
|
|
55
|
-
"response_types": ["code"]
|
|
56
|
-
}`;
|
|
57
|
-
|
|
58
|
-
// Second object with properties in different order
|
|
59
|
-
const clientJson2 = `{
|
|
60
|
-
"response_types": ["code"],
|
|
61
|
-
"grant_types": ["authorization_code", "refresh_token"],
|
|
62
|
-
"token_endpoint_auth_method": "none",
|
|
63
|
-
"redirect_uris": ["http://localhost:6274/oauth/callback"],
|
|
64
|
-
"client_uri": "https://github.com/modelcontextprotocol/inspector",
|
|
65
|
-
"client_name": "MCP Inspector"
|
|
66
|
-
}`;
|
|
67
|
-
|
|
68
|
-
const client1 = JSON.parse(clientJson1) as OAuthClient;
|
|
69
|
-
const client2 = JSON.parse(clientJson2) as OAuthClient;
|
|
70
|
-
|
|
71
|
-
const id1 = service.generateClientId(client1);
|
|
72
|
-
const id2 = service.generateClientId(client2);
|
|
73
|
-
|
|
74
|
-
expect(id1).toBe(id2);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('should generate consistent client IDs regardless of array order', () => {
|
|
78
|
-
// First object with arrays in one order
|
|
79
|
-
const clientJson1 = `{
|
|
80
|
-
"client_name": "MCP Inspector",
|
|
81
|
-
"client_uri": "https://github.com/modelcontextprotocol/inspector",
|
|
82
|
-
"redirect_uris": [
|
|
83
|
-
"http://localhost:6274/oauth/callback",
|
|
84
|
-
"http://localhost:8080/callback",
|
|
85
|
-
"http://127.0.0.1:3000/auth"
|
|
86
|
-
],
|
|
87
|
-
"token_endpoint_auth_method": "none",
|
|
88
|
-
"grant_types": [
|
|
89
|
-
"authorization_code",
|
|
90
|
-
"refresh_token",
|
|
91
|
-
"client_credentials"
|
|
92
|
-
],
|
|
93
|
-
"response_types": ["code", "token"]
|
|
94
|
-
}`;
|
|
95
|
-
|
|
96
|
-
// Second object with arrays in different order
|
|
97
|
-
const clientJson2 = `{
|
|
98
|
-
"client_name": "MCP Inspector",
|
|
99
|
-
"client_uri": "https://github.com/modelcontextprotocol/inspector",
|
|
100
|
-
"redirect_uris": [
|
|
101
|
-
"http://127.0.0.1:3000/auth",
|
|
102
|
-
"http://localhost:6274/oauth/callback",
|
|
103
|
-
"http://localhost:8080/callback"
|
|
104
|
-
],
|
|
105
|
-
"token_endpoint_auth_method": "none",
|
|
106
|
-
"grant_types": ["client_credentials", "authorization_code", "refresh_token"],
|
|
107
|
-
"response_types": ["token", "code"]
|
|
108
|
-
}`;
|
|
109
|
-
|
|
110
|
-
const client1 = JSON.parse(clientJson1) as OAuthClient;
|
|
111
|
-
const client2 = JSON.parse(clientJson2) as OAuthClient;
|
|
112
|
-
|
|
113
|
-
const id1 = service.generateClientId(client1);
|
|
114
|
-
const id2 = service.generateClientId(client2);
|
|
115
|
-
|
|
116
|
-
expect(id1).toBe(id2);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it('should generate consistent client IDs regardless of both property and array order', () => {
|
|
120
|
-
// First object with mixed ordering
|
|
121
|
-
const clientJson1 = `{
|
|
122
|
-
"grant_types": ["refresh_token", "authorization_code"],
|
|
123
|
-
"client_name": "MCP Inspector",
|
|
124
|
-
"response_types": ["code"],
|
|
125
|
-
"redirect_uris": [
|
|
126
|
-
"http://localhost:8080/callback",
|
|
127
|
-
"http://localhost:6274/oauth/callback"
|
|
128
|
-
],
|
|
129
|
-
"token_endpoint_auth_method": "none",
|
|
130
|
-
"client_uri": "https://github.com/modelcontextprotocol/inspector"
|
|
131
|
-
}`;
|
|
132
|
-
|
|
133
|
-
// Second object with different mixed ordering
|
|
134
|
-
const clientJson2 = `{
|
|
135
|
-
"client_uri": "https://github.com/modelcontextprotocol/inspector",
|
|
136
|
-
"token_endpoint_auth_method": "none",
|
|
137
|
-
"redirect_uris": [
|
|
138
|
-
"http://localhost:6274/oauth/callback",
|
|
139
|
-
"http://localhost:8080/callback"
|
|
140
|
-
],
|
|
141
|
-
"response_types": ["code"],
|
|
142
|
-
"client_name": "MCP Inspector",
|
|
143
|
-
"grant_types": ["authorization_code", "refresh_token"]
|
|
144
|
-
}`;
|
|
145
|
-
|
|
146
|
-
const client1 = JSON.parse(clientJson1) as OAuthClient;
|
|
147
|
-
const client2 = JSON.parse(clientJson2) as OAuthClient;
|
|
148
|
-
|
|
149
|
-
const id1 = service.generateClientId(client1);
|
|
150
|
-
const id2 = service.generateClientId(client2);
|
|
151
|
-
|
|
152
|
-
expect(id1).toBe(id2);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it('should generate different client IDs for different objects', () => {
|
|
156
|
-
const client1: Partial<OAuthClient> = {
|
|
157
|
-
client_name: 'MCP Inspector',
|
|
158
|
-
client_uri: 'https://github.com/modelcontextprotocol/inspector',
|
|
159
|
-
redirect_uris: ['http://localhost:6274/oauth/callback'],
|
|
160
|
-
token_endpoint_auth_method: 'none',
|
|
161
|
-
grant_types: ['authorization_code', 'refresh_token'],
|
|
162
|
-
response_types: ['code'],
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
const client2: Partial<OAuthClient> = {
|
|
166
|
-
client_name: 'Different App', // Changed client name
|
|
167
|
-
client_uri: 'https://github.com/modelcontextprotocol/inspector',
|
|
168
|
-
redirect_uris: ['http://localhost:6274/oauth/callback'],
|
|
169
|
-
token_endpoint_auth_method: 'none',
|
|
170
|
-
grant_types: ['authorization_code', 'refresh_token'],
|
|
171
|
-
response_types: ['code'],
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
const id1 = service.generateClientId(client1 as OAuthClient);
|
|
175
|
-
const id2 = service.generateClientId(client2 as OAuthClient);
|
|
176
|
-
|
|
177
|
-
expect(id1).not.toBe(id2);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it('should generate different client IDs when array contents differ', () => {
|
|
181
|
-
const client1: Partial<OAuthClient> = {
|
|
182
|
-
client_name: 'MCP Inspector',
|
|
183
|
-
client_uri: 'https://github.com/modelcontextprotocol/inspector',
|
|
184
|
-
redirect_uris: ['http://localhost:6274/oauth/callback'],
|
|
185
|
-
token_endpoint_auth_method: 'none',
|
|
186
|
-
grant_types: ['authorization_code', 'refresh_token'],
|
|
187
|
-
response_types: ['code'],
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
const client2: Partial<OAuthClient> = {
|
|
191
|
-
client_name: 'MCP Inspector',
|
|
192
|
-
client_uri: 'https://github.com/modelcontextprotocol/inspector',
|
|
193
|
-
redirect_uris: ['http://localhost:6274/oauth/callback'],
|
|
194
|
-
token_endpoint_auth_method: 'none',
|
|
195
|
-
grant_types: ['authorization_code'], // Removed 'refresh_token'
|
|
196
|
-
response_types: ['code'],
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
const id1 = service.generateClientId(client1 as OAuthClient);
|
|
200
|
-
const id2 = service.generateClientId(client2 as OAuthClient);
|
|
201
|
-
|
|
202
|
-
expect(id1).not.toBe(id2);
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it('should include normalized client name in the generated ID', () => {
|
|
206
|
-
const client: Partial<OAuthClient> = {
|
|
207
|
-
client_name: 'MCP Inspector!@#', // Special characters
|
|
208
|
-
client_uri: 'https://github.com/modelcontextprotocol/inspector',
|
|
209
|
-
redirect_uris: ['http://localhost:6274/oauth/callback'],
|
|
210
|
-
token_endpoint_auth_method: 'none',
|
|
211
|
-
grant_types: ['authorization_code', 'refresh_token'],
|
|
212
|
-
response_types: ['code'],
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
const clientId = service.generateClientId(client as OAuthClient);
|
|
216
|
-
|
|
217
|
-
// Should start with normalized name (lowercase, alphanumeric only)
|
|
218
|
-
expect(clientId).toMatch(/^mcpinspector_[a-f0-9]{16}$/);
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
it('should generate IDs with consistent format', () => {
|
|
222
|
-
const client: Partial<OAuthClient> = {
|
|
223
|
-
client_name: 'Test App',
|
|
224
|
-
client_uri: 'https://example.com',
|
|
225
|
-
redirect_uris: ['http://localhost:3000/callback'],
|
|
226
|
-
token_endpoint_auth_method: 'none',
|
|
227
|
-
grant_types: ['authorization_code'],
|
|
228
|
-
response_types: ['code'],
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
const clientId = service.generateClientId(client as OAuthClient);
|
|
232
|
-
|
|
233
|
-
// Should match pattern: normalizedname_16hexchars
|
|
234
|
-
expect(clientId).toMatch(/^[a-z0-9]+_[a-f0-9]{16}$/);
|
|
235
|
-
|
|
236
|
-
// Should be consistent across multiple calls
|
|
237
|
-
const clientId2 = service.generateClientId(client as OAuthClient);
|
|
238
|
-
expect(clientId).toBe(clientId2);
|
|
239
|
-
});
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
describe('Client Management', () => {
|
|
243
|
-
const mockClient: OAuthClient = {
|
|
244
|
-
client_id: 'test-client-id',
|
|
245
|
-
client_name: 'Test Client',
|
|
246
|
-
client_description: 'A test OAuth client',
|
|
247
|
-
logo_uri: 'https://example.com/logo.png',
|
|
248
|
-
client_uri: 'https://example.com',
|
|
249
|
-
developer_name: 'Test Developer',
|
|
250
|
-
developer_email: 'test@example.com',
|
|
251
|
-
redirect_uris: ['http://localhost:3000/callback'],
|
|
252
|
-
grant_types: ['authorization_code', 'refresh_token'],
|
|
253
|
-
response_types: ['code'],
|
|
254
|
-
token_endpoint_auth_method: 'none',
|
|
255
|
-
created_at: new Date(),
|
|
256
|
-
updated_at: new Date(),
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
describe('storeClient', () => {
|
|
260
|
-
it('should store a client and return it', async () => {
|
|
261
|
-
const result = await service.storeClient(mockClient);
|
|
262
|
-
expect(result).toEqual(mockClient);
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
it('should allow retrieving the stored client', async () => {
|
|
266
|
-
await service.storeClient(mockClient);
|
|
267
|
-
const retrieved = await service.getClient(mockClient.client_id);
|
|
268
|
-
expect(retrieved).toEqual(mockClient);
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
it('should overwrite existing client with same ID', async () => {
|
|
272
|
-
await service.storeClient(mockClient);
|
|
273
|
-
|
|
274
|
-
const updatedClient = { ...mockClient, client_name: 'Updated Client' };
|
|
275
|
-
await service.storeClient(updatedClient);
|
|
276
|
-
|
|
277
|
-
const retrieved = await service.getClient(mockClient.client_id);
|
|
278
|
-
expect(retrieved?.client_name).toBe('Updated Client');
|
|
279
|
-
});
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
describe('getClient', () => {
|
|
283
|
-
it('should return undefined for non-existent client', async () => {
|
|
284
|
-
const result = await service.getClient('non-existent-id');
|
|
285
|
-
expect(result).toBeUndefined();
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
it('should return the correct client when it exists', async () => {
|
|
289
|
-
await service.storeClient(mockClient);
|
|
290
|
-
const result = await service.getClient(mockClient.client_id);
|
|
291
|
-
expect(result).toEqual(mockClient);
|
|
292
|
-
});
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
describe('findClient', () => {
|
|
296
|
-
it('should return undefined for non-existent client name', async () => {
|
|
297
|
-
const result = await service.findClient('Non-existent Client');
|
|
298
|
-
expect(result).toBeUndefined();
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
it('should find client by exact name match', async () => {
|
|
302
|
-
await service.storeClient(mockClient);
|
|
303
|
-
const result = await service.findClient(mockClient.client_name);
|
|
304
|
-
expect(result).toEqual(mockClient);
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
it('should be case sensitive', async () => {
|
|
308
|
-
await service.storeClient(mockClient);
|
|
309
|
-
const result = await service.findClient(
|
|
310
|
-
mockClient.client_name.toUpperCase(),
|
|
311
|
-
);
|
|
312
|
-
expect(result).toBeUndefined();
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
it('should return first match when multiple clients exist', async () => {
|
|
316
|
-
const client1 = { ...mockClient, client_id: 'client-1' };
|
|
317
|
-
const client2 = {
|
|
318
|
-
...mockClient,
|
|
319
|
-
client_id: 'client-2',
|
|
320
|
-
client_name: 'Different Client',
|
|
321
|
-
};
|
|
322
|
-
|
|
323
|
-
await service.storeClient(client1);
|
|
324
|
-
await service.storeClient(client2);
|
|
325
|
-
|
|
326
|
-
const result = await service.findClient(client1.client_name);
|
|
327
|
-
expect(result).toEqual(client1);
|
|
328
|
-
});
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
describe('Authorization Code Management', () => {
|
|
333
|
-
const mockAuthCode: AuthorizationCode = {
|
|
334
|
-
code: 'test-auth-code',
|
|
335
|
-
user_id: 'user-123',
|
|
336
|
-
client_id: 'client-123',
|
|
337
|
-
redirect_uri: 'http://localhost:3000/callback',
|
|
338
|
-
code_challenge: 'test-challenge',
|
|
339
|
-
code_challenge_method: 'S256',
|
|
340
|
-
expires_at: Date.now() + 600000, // 10 minutes from now
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
describe('storeAuthCode', () => {
|
|
344
|
-
it('should store an authorization code', async () => {
|
|
345
|
-
await service.storeAuthCode(mockAuthCode);
|
|
346
|
-
const retrieved = await service.getAuthCode(mockAuthCode.code);
|
|
347
|
-
expect(retrieved).toEqual(mockAuthCode);
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
it('should overwrite existing code with same value', async () => {
|
|
351
|
-
await service.storeAuthCode(mockAuthCode);
|
|
352
|
-
|
|
353
|
-
const updatedCode = { ...mockAuthCode, user_id: 'updated-user' };
|
|
354
|
-
await service.storeAuthCode(updatedCode);
|
|
355
|
-
|
|
356
|
-
const retrieved = await service.getAuthCode(mockAuthCode.code);
|
|
357
|
-
expect(retrieved?.user_id).toBe('updated-user');
|
|
358
|
-
});
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
describe('getAuthCode', () => {
|
|
362
|
-
it('should return undefined for non-existent code', async () => {
|
|
363
|
-
const result = await service.getAuthCode('non-existent-code');
|
|
364
|
-
expect(result).toBeUndefined();
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
it('should return the correct authorization code when it exists', async () => {
|
|
368
|
-
await service.storeAuthCode(mockAuthCode);
|
|
369
|
-
const result = await service.getAuthCode(mockAuthCode.code);
|
|
370
|
-
expect(result).toEqual(mockAuthCode);
|
|
371
|
-
});
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
describe('removeAuthCode', () => {
|
|
375
|
-
it('should remove an authorization code', async () => {
|
|
376
|
-
await service.storeAuthCode(mockAuthCode);
|
|
377
|
-
await service.removeAuthCode(mockAuthCode.code);
|
|
378
|
-
|
|
379
|
-
const retrieved = await service.getAuthCode(mockAuthCode.code);
|
|
380
|
-
expect(retrieved).toBeUndefined();
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
it('should not throw when removing non-existent code', async () => {
|
|
384
|
-
await expect(
|
|
385
|
-
service.removeAuthCode('non-existent-code'),
|
|
386
|
-
).resolves.toBeUndefined();
|
|
387
|
-
});
|
|
388
|
-
});
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
describe('OAuth Session Management', () => {
|
|
392
|
-
const mockSession: OAuthSession = {
|
|
393
|
-
sessionId: 'session-123',
|
|
394
|
-
state: 'test-state',
|
|
395
|
-
clientId: 'client-123',
|
|
396
|
-
redirectUri: 'http://localhost:3000/callback',
|
|
397
|
-
codeChallenge: 'test-challenge',
|
|
398
|
-
codeChallengeMethod: 'S256',
|
|
399
|
-
oauthState: 'oauth-state-123',
|
|
400
|
-
resource: 'test-resource',
|
|
401
|
-
expiresAt: Date.now() + 3600000, // 1 hour from now
|
|
402
|
-
};
|
|
403
|
-
|
|
404
|
-
const expiredSession: OAuthSession = {
|
|
405
|
-
...mockSession,
|
|
406
|
-
sessionId: 'expired-session',
|
|
407
|
-
expiresAt: Date.now() - 1000, // 1 second ago
|
|
408
|
-
};
|
|
409
|
-
|
|
410
|
-
describe('storeOAuthSession', () => {
|
|
411
|
-
it('should store an OAuth session', async () => {
|
|
412
|
-
const sessionId = 'session-123';
|
|
413
|
-
await service.storeOAuthSession(sessionId, mockSession);
|
|
414
|
-
|
|
415
|
-
const retrieved = await service.getOAuthSession(sessionId);
|
|
416
|
-
expect(retrieved).toEqual(mockSession);
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
it('should overwrite existing session with same ID', async () => {
|
|
420
|
-
const sessionId = 'session-123';
|
|
421
|
-
await service.storeOAuthSession(sessionId, mockSession);
|
|
422
|
-
|
|
423
|
-
const updatedSession = { ...mockSession, state: 'updated-state' };
|
|
424
|
-
await service.storeOAuthSession(sessionId, updatedSession);
|
|
425
|
-
|
|
426
|
-
const retrieved = await service.getOAuthSession(sessionId);
|
|
427
|
-
expect(retrieved?.state).toBe('updated-state');
|
|
428
|
-
});
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
describe('getOAuthSession', () => {
|
|
432
|
-
it('should return undefined for non-existent session', async () => {
|
|
433
|
-
const result = await service.getOAuthSession('non-existent-session');
|
|
434
|
-
expect(result).toBeUndefined();
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
it('should return the correct OAuth session when it exists', async () => {
|
|
438
|
-
const sessionId = 'session-123';
|
|
439
|
-
await service.storeOAuthSession(sessionId, mockSession);
|
|
440
|
-
|
|
441
|
-
const result = await service.getOAuthSession(sessionId);
|
|
442
|
-
expect(result).toEqual(mockSession);
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
it('should return undefined and auto-remove expired sessions', async () => {
|
|
446
|
-
const sessionId = 'expired-session';
|
|
447
|
-
await service.storeOAuthSession(sessionId, expiredSession);
|
|
448
|
-
|
|
449
|
-
const result = await service.getOAuthSession(sessionId);
|
|
450
|
-
expect(result).toBeUndefined();
|
|
451
|
-
|
|
452
|
-
// Verify it was actually removed
|
|
453
|
-
const result2 = await service.getOAuthSession(sessionId);
|
|
454
|
-
expect(result2).toBeUndefined();
|
|
455
|
-
});
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
describe('removeOAuthSession', () => {
|
|
459
|
-
it('should remove an OAuth session', async () => {
|
|
460
|
-
const sessionId = 'session-123';
|
|
461
|
-
await service.storeOAuthSession(sessionId, mockSession);
|
|
462
|
-
await service.removeOAuthSession(sessionId);
|
|
463
|
-
|
|
464
|
-
const retrieved = await service.getOAuthSession(sessionId);
|
|
465
|
-
expect(retrieved).toBeUndefined();
|
|
466
|
-
});
|
|
467
|
-
|
|
468
|
-
it('should not throw when removing non-existent session', async () => {
|
|
469
|
-
await expect(
|
|
470
|
-
service.removeOAuthSession('non-existent-session'),
|
|
471
|
-
).resolves.toBeUndefined();
|
|
472
|
-
});
|
|
473
|
-
});
|
|
474
|
-
});
|
|
475
|
-
});
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common';
|
|
2
|
-
import { createHash } from 'crypto';
|
|
3
|
-
import {
|
|
4
|
-
OAuthSession,
|
|
5
|
-
OAuthUserProfile,
|
|
6
|
-
} from '../providers/oauth-provider.interface';
|
|
7
|
-
import type {
|
|
8
|
-
AuthorizationCode,
|
|
9
|
-
IOAuthStore,
|
|
10
|
-
OAuthClient,
|
|
11
|
-
} from './oauth-store.interface';
|
|
12
|
-
|
|
13
|
-
// In-memory storage (in production, use a database)
|
|
14
|
-
@Injectable()
|
|
15
|
-
export class MemoryStore implements IOAuthStore {
|
|
16
|
-
private clients = new Map<string, OAuthClient>();
|
|
17
|
-
private authCodes = new Map<string, AuthorizationCode>();
|
|
18
|
-
private oauthSessions = new Map<string, OAuthSession>();
|
|
19
|
-
private userProfiles = new Map<
|
|
20
|
-
string,
|
|
21
|
-
OAuthUserProfile & { profile_id: string; provider: string }
|
|
22
|
-
>(); // profile_id -> profile
|
|
23
|
-
private providerUserIndex = new Map<string, string>(); // key(provider:userId) -> profile_id
|
|
24
|
-
|
|
25
|
-
async storeClient(client: OAuthClient): Promise<OAuthClient> {
|
|
26
|
-
this.clients.set(client.client_id, client);
|
|
27
|
-
return client;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async getClient(client_id: string): Promise<OAuthClient | undefined> {
|
|
31
|
-
return this.clients.get(client_id);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async findClient(client_name: string): Promise<OAuthClient | undefined> {
|
|
35
|
-
for (const client of this.clients.values()) {
|
|
36
|
-
if (client.client_name === client_name) {
|
|
37
|
-
return client;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return undefined;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async storeAuthCode(code: AuthorizationCode): Promise<void> {
|
|
44
|
-
this.authCodes.set(code.code, code);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async getAuthCode(code: string): Promise<AuthorizationCode | undefined> {
|
|
48
|
-
return this.authCodes.get(code);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async removeAuthCode(code: string): Promise<void> {
|
|
52
|
-
this.authCodes.delete(code);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// New OAuth session methods for provider-agnostic flow
|
|
56
|
-
async storeOAuthSession(
|
|
57
|
-
sessionId: string,
|
|
58
|
-
session: OAuthSession,
|
|
59
|
-
): Promise<void> {
|
|
60
|
-
this.oauthSessions.set(sessionId, session);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async getOAuthSession(sessionId: string): Promise<OAuthSession | undefined> {
|
|
64
|
-
const session = this.oauthSessions.get(sessionId);
|
|
65
|
-
if (session && session.expiresAt < Date.now()) {
|
|
66
|
-
this.oauthSessions.delete(sessionId);
|
|
67
|
-
return undefined;
|
|
68
|
-
}
|
|
69
|
-
return session;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async removeOAuthSession(sessionId: string): Promise<void> {
|
|
73
|
-
this.oauthSessions.delete(sessionId);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
generateClientId(client: OAuthClient): string {
|
|
77
|
-
// Create deterministic client ID based on entire client object
|
|
78
|
-
const normalizedClient = this.normalizeClientObject(client);
|
|
79
|
-
const clientString = JSON.stringify(normalizedClient);
|
|
80
|
-
const hash = createHash('sha256').update(clientString).digest('hex');
|
|
81
|
-
|
|
82
|
-
// Use first 16 characters of hash with client name prefix for readability
|
|
83
|
-
const normalizedName = client.client_name
|
|
84
|
-
.toLowerCase()
|
|
85
|
-
.replace(/[^a-z0-9]/g, '');
|
|
86
|
-
return `${normalizedName}_${hash.substring(0, 16)}`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
private normalizeClientObject(client: OAuthClient): any {
|
|
90
|
-
// Create a normalized version of the client object for consistent hashing
|
|
91
|
-
const normalized: any = {};
|
|
92
|
-
|
|
93
|
-
// Sort object keys to ensure consistent ordering
|
|
94
|
-
const sortedKeys = Object.keys(client).sort();
|
|
95
|
-
|
|
96
|
-
for (const key of sortedKeys) {
|
|
97
|
-
const value = (client as any)[key];
|
|
98
|
-
if (Array.isArray(value)) {
|
|
99
|
-
// Sort arrays to ensure consistent ordering
|
|
100
|
-
normalized[key] = [...value].sort();
|
|
101
|
-
} else {
|
|
102
|
-
normalized[key] = value;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return normalized;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// User profile management
|
|
110
|
-
async upsertUserProfile(
|
|
111
|
-
profile: OAuthUserProfile,
|
|
112
|
-
provider: string,
|
|
113
|
-
): Promise<string> {
|
|
114
|
-
const key = `${provider}:${profile.id}`;
|
|
115
|
-
let profileId = this.providerUserIndex.get(key);
|
|
116
|
-
if (!profileId) {
|
|
117
|
-
// create new
|
|
118
|
-
profileId = this.generateProfileId(provider, profile.id);
|
|
119
|
-
this.providerUserIndex.set(key, profileId);
|
|
120
|
-
}
|
|
121
|
-
this.userProfiles.set(profileId, {
|
|
122
|
-
profile_id: profileId,
|
|
123
|
-
provider,
|
|
124
|
-
...profile,
|
|
125
|
-
});
|
|
126
|
-
return profileId;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
async getUserProfileById(
|
|
130
|
-
profileId: string,
|
|
131
|
-
): Promise<
|
|
132
|
-
(OAuthUserProfile & { profile_id: string; provider: string }) | undefined
|
|
133
|
-
> {
|
|
134
|
-
return this.userProfiles.get(profileId);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
private generateProfileId(provider: string, providerUserId: string): string {
|
|
138
|
-
const input = `${provider}:${providerUserId}`;
|
|
139
|
-
return createHash('sha256').update(input).digest('hex').slice(0, 24);
|
|
140
|
-
}
|
|
141
|
-
}
|