@rekog/mcp-nest 1.7.1 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +1 -1
  2. package/dist/authz/adapters/github.adapter.d.ts +40 -0
  3. package/dist/authz/adapters/github.adapter.d.ts.map +1 -0
  4. package/dist/authz/adapters/github.adapter.js +212 -0
  5. package/dist/authz/adapters/github.adapter.js.map +1 -0
  6. package/dist/authz/adapters/oidc.adapter.d.ts +21 -0
  7. package/dist/authz/adapters/oidc.adapter.d.ts.map +1 -0
  8. package/dist/authz/adapters/oidc.adapter.js +125 -0
  9. package/dist/authz/adapters/oidc.adapter.js.map +1 -0
  10. package/dist/authz/controllers/resource-metadata.controller.d.ts +62 -0
  11. package/dist/authz/controllers/resource-metadata.controller.d.ts.map +1 -0
  12. package/dist/authz/controllers/resource-metadata.controller.js +84 -0
  13. package/dist/authz/controllers/resource-metadata.controller.js.map +1 -0
  14. package/dist/authz/controllers/well-known.controller.d.ts +63 -0
  15. package/dist/authz/controllers/well-known.controller.d.ts.map +1 -0
  16. package/dist/authz/controllers/well-known.controller.js +131 -0
  17. package/dist/authz/controllers/well-known.controller.js.map +1 -0
  18. package/dist/authz/examples/oidc-provider-example.d.ts +3 -0
  19. package/dist/authz/examples/oidc-provider-example.d.ts.map +1 -0
  20. package/dist/authz/examples/oidc-provider-example.js +51 -0
  21. package/dist/authz/examples/oidc-provider-example.js.map +1 -0
  22. package/dist/authz/guards/jwt-auth.guard.js +1 -1
  23. package/dist/authz/guards/jwt-auth.guard.js.map +1 -1
  24. package/dist/authz/mcp-oauth.controller.d.ts +20 -11
  25. package/dist/authz/mcp-oauth.controller.d.ts.map +1 -1
  26. package/dist/authz/mcp-oauth.controller.js +91 -17
  27. package/dist/authz/mcp-oauth.controller.js.map +1 -1
  28. package/dist/authz/mcp-oauth.module.d.ts.map +1 -1
  29. package/dist/authz/mcp-oauth.module.js +2 -2
  30. package/dist/authz/mcp-oauth.module.js.map +1 -1
  31. package/dist/authz/oidc-provider.controller.d.ts +48 -0
  32. package/dist/authz/oidc-provider.controller.d.ts.map +1 -0
  33. package/dist/authz/oidc-provider.controller.js +194 -0
  34. package/dist/authz/oidc-provider.controller.js.map +1 -0
  35. package/dist/authz/oidc-provider.module.d.ts +11 -0
  36. package/dist/authz/oidc-provider.module.d.ts.map +1 -0
  37. package/dist/authz/oidc-provider.module.js +275 -0
  38. package/dist/authz/oidc-provider.module.js.map +1 -0
  39. package/dist/authz/providers/oauth-provider.interface.d.ts +1 -1
  40. package/dist/authz/providers/oauth-provider.interface.d.ts.map +1 -1
  41. package/dist/authz/providers/oauth-provider.interface.js.map +1 -1
  42. package/dist/authz/services/client.service.d.ts.map +1 -1
  43. package/dist/authz/services/client.service.js +14 -1
  44. package/dist/authz/services/client.service.js.map +1 -1
  45. package/dist/authz/services/jwt-token.service.d.ts +1 -0
  46. package/dist/authz/services/jwt-token.service.d.ts.map +1 -1
  47. package/dist/authz/services/jwt-token.service.js +10 -6
  48. package/dist/authz/services/jwt-token.service.js.map +1 -1
  49. package/dist/authz/stores/oauth-store.interface.d.ts +1 -0
  50. package/dist/authz/stores/oauth-store.interface.d.ts.map +1 -1
  51. package/dist/authz/stores/oauth-store.interface.js.map +1 -1
  52. package/dist/authz/stores/typeorm/entities/authorization-code.entity.d.ts +1 -0
  53. package/dist/authz/stores/typeorm/entities/authorization-code.entity.d.ts.map +1 -1
  54. package/dist/authz/stores/typeorm/entities/authorization-code.entity.js +4 -0
  55. package/dist/authz/stores/typeorm/entities/authorization-code.entity.js.map +1 -1
  56. package/dist/authz/stores/typeorm/entities/oauth-client.entity.d.ts +1 -0
  57. package/dist/authz/stores/typeorm/entities/oauth-client.entity.d.ts.map +1 -1
  58. package/dist/authz/stores/typeorm/entities/oauth-client.entity.js +4 -0
  59. package/dist/authz/stores/typeorm/entities/oauth-client.entity.js.map +1 -1
  60. package/dist/mcp/decorators/prompt.decorator.d.ts.map +1 -1
  61. package/dist/mcp/decorators/resource-template.decorator.d.ts.map +1 -1
  62. package/dist/mcp/decorators/resource.decorator.d.ts.map +1 -1
  63. package/dist/mcp/decorators/tool.decorator.d.ts.map +1 -1
  64. package/package.json +2 -2
  65. package/src/authz/guards/jwt-auth.guard.ts +1 -1
  66. package/src/authz/mcp-oauth.controller.ts +152 -15
  67. package/src/authz/mcp-oauth.module.ts +4 -2
  68. package/src/authz/providers/oauth-provider.interface.ts +1 -1
  69. package/src/authz/services/client.service.ts +25 -1
  70. package/src/authz/services/jwt-token.service.ts +16 -8
  71. package/src/authz/stores/oauth-store.interface.ts +1 -0
  72. package/src/authz/stores/typeorm/entities/authorization-code.entity.ts +3 -0
  73. package/src/authz/stores/typeorm/entities/oauth-client.entity.ts +3 -0
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-oauth.controller.js","sourceRoot":"","sources":["../../src/authz/mcp-oauth.controller.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BadRequestException,\n Body,\n Controller,\n Get,\n Inject,\n Logger,\n Next,\n Post,\n Query,\n Req,\n Res,\n UseGuards,\n} from '@nestjs/common';\nimport { createHash, randomBytes } from 'crypto';\nimport { Request as ExpressRequest, NextFunction, Response } from 'express';\nimport passport from 'passport';\nimport { AuthenticatedRequest, McpAuthJwtGuard } from './guards/jwt-auth.guard';\nimport {\n OAuthEndpointConfiguration,\n OAuthModuleOptions,\n OAuthSession,\n OAuthUserProfile,\n} from './providers/oauth-provider.interface';\nimport { ClientService } from './services/client.service';\nimport { JwtTokenService, TokenPair } from './services/jwt-token.service';\nimport { STRATEGY_NAME } from './services/oauth-strategy.service';\nimport {\n ClientRegistrationDto,\n IOAuthStore,\n} from './stores/oauth-store.interface';\nimport { normalizeEndpoint } from '../mcp/utils/normalize-endpoint';\n\ninterface OAuthCallbackRequest extends ExpressRequest {\n user?: {\n profile: OAuthUserProfile;\n accessToken: string;\n provider: string;\n };\n}\n\nexport function createMcpOAuthController(\n endpoints: OAuthEndpointConfiguration = {},\n) {\n @Controller()\n class McpOAuthController {\n readonly logger = new Logger(McpOAuthController.name);\n readonly serverUrl: string;\n readonly isProduction: boolean;\n readonly options: OAuthModuleOptions;\n constructor(\n @Inject('OAUTH_MODULE_OPTIONS') options: OAuthModuleOptions,\n @Inject('IOAuthStore') readonly store: IOAuthStore,\n readonly jwtTokenService: JwtTokenService,\n readonly clientService: ClientService,\n ) {\n this.serverUrl = options.serverUrl;\n this.isProduction = options.cookieSecure;\n this.options = options;\n }\n\n // OAuth endpoints\n @Get(endpoints.wellKnown)\n getAuthorizationServerMetadata() {\n return {\n issuer: this.serverUrl,\n authorization_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints.authorize}`,\n ),\n token_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints.token}`,\n ),\n registration_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints.register}`,\n ),\n response_types_supported: ['code'],\n response_modes_supported: ['query'],\n grant_types_supported: ['authorization_code', 'refresh_token'],\n token_endpoint_auth_methods_supported: [\n 'client_secret_basic',\n 'client_secret_post',\n 'none',\n ],\n revocation_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints?.revoke}`,\n ),\n code_challenge_methods_supported: ['plain', 'S256'],\n };\n }\n\n @Post(endpoints.register)\n async registerClient(@Body() registrationDto: ClientRegistrationDto) {\n return await this.clientService.registerClient(registrationDto);\n }\n\n @Get(endpoints.authorize)\n async authorize(\n @Query() query: any,\n @Req()\n req: any,\n @Res() res: Response,\n @Next() next: NextFunction,\n ) {\n const {\n response_type,\n client_id,\n redirect_uri,\n code_challenge,\n code_challenge_method,\n state,\n } = query;\n const resource = this.options.resource;\n if (response_type !== 'code') {\n throw new BadRequestException('Only response_type=code is supported');\n }\n\n if (!client_id) {\n throw new BadRequestException('Missing required parameters');\n }\n\n // Validate client and redirect URI\n const client = await this.clientService.getClient(client_id);\n if (!client) {\n throw new BadRequestException('Invalid client_id');\n }\n\n const validRedirect = await this.clientService.validateRedirectUri(\n client_id,\n redirect_uri,\n );\n if (!validRedirect) {\n throw new BadRequestException('Invalid redirect_uri');\n }\n\n // Create OAuth session\n const sessionId = randomBytes(32).toString('base64url');\n const sessionState = randomBytes(32).toString('base64url');\n\n const oauthSession: OAuthSession = {\n sessionId,\n state: sessionState,\n clientId: client_id,\n redirectUri: redirect_uri,\n codeChallenge: code_challenge,\n codeChallengeMethod: code_challenge_method || 'plain',\n oauthState: state,\n scope: query.scope || '',\n resource,\n expiresAt: Date.now() + this.options.oauthSessionExpiresIn,\n };\n\n await this.store.storeOAuthSession(sessionId, oauthSession);\n\n // Set session cookie\n res.cookie('oauth_session', sessionId, {\n httpOnly: true,\n secure: this.isProduction,\n maxAge: this.options.oauthSessionExpiresIn,\n });\n\n // Store state for passport\n res.cookie('oauth_state', sessionState, {\n httpOnly: true,\n secure: this.isProduction,\n maxAge: this.options.oauthSessionExpiresIn,\n });\n\n // Redirect to the provider's auth endpoint\n passport.authenticate(STRATEGY_NAME, {\n state: req.cookies?.oauth_state,\n })(req, res, next);\n }\n\n @Get(endpoints.callback)\n handleProviderCallback(\n @Req() req: OAuthCallbackRequest,\n @Res() res: Response,\n @Next() next: NextFunction,\n ) {\n // Use a custom callback to handle the authentication result\n passport.authenticate(\n STRATEGY_NAME,\n { session: false },\n async (err: any, user: any) => {\n try {\n if (err) {\n this.logger.error('OAuth callback error:', err);\n throw new BadRequestException('Authentication failed');\n }\n\n if (!user) {\n throw new BadRequestException('Authentication failed');\n }\n\n req.user = user;\n await this.processAuthenticationSuccess(req, res);\n } catch (error) {\n next(error);\n }\n },\n )(req, res, next);\n }\n\n async processAuthenticationSuccess(\n req: OAuthCallbackRequest,\n res: Response,\n ) {\n const user = req.user;\n if (!user) {\n throw new BadRequestException('Authentication failed');\n }\n\n const sessionId = req.cookies?.oauth_session;\n if (!sessionId) {\n throw new BadRequestException('Missing OAuth session');\n }\n\n const session = await this.store.getOAuthSession(sessionId);\n if (!session) {\n throw new BadRequestException('Invalid or expired OAuth session');\n }\n\n // Verify state\n const stateFromCookie = req.cookies?.oauth_state;\n if (session.state !== stateFromCookie) {\n throw new BadRequestException('Invalid state parameter');\n }\n\n // Generate JWT for UI access\n const jwt = this.jwtTokenService.generateUserToken(\n user.profile.username,\n user.profile,\n );\n\n // Set JWT token as cookie for UI endpoints\n res.cookie('auth_token', jwt, {\n httpOnly: true,\n secure: this.isProduction,\n maxAge: this.options.cookieMaxAge,\n });\n\n // Clear temporary cookies\n res.clearCookie('oauth_session');\n res.clearCookie('oauth_state');\n\n // Generate authorization code\n const authCode = randomBytes(32).toString('base64url');\n\n // Store the auth code\n await this.store.storeAuthCode({\n code: authCode,\n user_id: user.profile.username,\n client_id: session.clientId!,\n redirect_uri: session.redirectUri!,\n code_challenge: session.codeChallenge!,\n code_challenge_method: session.codeChallengeMethod!,\n expires_at: Date.now() + this.options.authCodeExpiresIn,\n resource: session.resource,\n scope: session.scope,\n github_access_token: '', // No longer provider-specific\n });\n\n // Build redirect URL with authorization code\n const redirectUrl = new URL(session.redirectUri!);\n redirectUrl.searchParams.set('code', authCode);\n if (session.oauthState) {\n redirectUrl.searchParams.set('state', session.oauthState);\n }\n\n // Clean up session\n await this.store.removeOAuthSession(sessionId);\n\n res.redirect(redirectUrl.toString());\n }\n\n // Token endpoints (remain the same)\n @Post(endpoints.token)\n async exchangeToken(@Body() body: any): Promise<TokenPair> {\n const {\n grant_type,\n code,\n code_verifier,\n redirect_uri,\n client_id,\n refresh_token,\n } = body;\n\n if (grant_type === 'authorization_code') {\n return this.handleAuthorizationCodeGrant(\n code,\n code_verifier,\n redirect_uri,\n client_id,\n );\n } else if (grant_type === 'refresh_token') {\n return this.handleRefreshTokenGrant(refresh_token);\n } else {\n throw new BadRequestException('Unsupported grant_type');\n }\n }\n\n async handleAuthorizationCodeGrant(\n code: string,\n code_verifier: string,\n _redirect_uri: string,\n client_id: string,\n ): Promise<TokenPair> {\n this.logger.debug('handleAuthorizationCodeGrant - Params:', {\n code,\n client_id,\n });\n const authCode = await this.store.getAuthCode(code);\n if (!authCode) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - Invalid authorization code:',\n code,\n );\n throw new BadRequestException('Invalid authorization code');\n }\n if (authCode.expires_at < Date.now()) {\n await this.store.removeAuthCode(code);\n this.logger.error(\n 'handleAuthorizationCodeGrant - Authorization code expired:',\n code,\n );\n throw new BadRequestException('Authorization code has expired');\n }\n if (authCode.client_id !== client_id) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - Client ID mismatch:',\n { expected: authCode.client_id, got: client_id },\n );\n throw new BadRequestException('Client ID mismatch');\n }\n if (authCode.code_challenge) {\n const isValid = this.validatePKCE(\n code_verifier,\n authCode.code_challenge,\n authCode.code_challenge_method,\n );\n if (!isValid) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - Invalid PKCE verification',\n );\n throw new BadRequestException('Invalid PKCE verification');\n }\n }\n if (!authCode.resource) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - No resource associated with code',\n );\n throw new BadRequestException(\n 'Authorization code is not associated with a resource',\n );\n }\n const tokens = this.jwtTokenService.generateTokenPair(\n authCode.user_id,\n client_id,\n authCode.scope,\n authCode.resource,\n );\n await this.store.removeAuthCode(code);\n this.logger.log(\n 'handleAuthorizationCodeGrant - Token pair generated for user:',\n authCode.user_id,\n );\n return tokens;\n }\n\n handleRefreshTokenGrant(refresh_token: string): TokenPair {\n const newTokens = this.jwtTokenService.refreshAccessToken(refresh_token);\n if (!newTokens) {\n throw new BadRequestException('Failed to refresh token');\n }\n\n return newTokens;\n }\n\n @Get(endpoints.validate)\n @UseGuards(McpAuthJwtGuard)\n validateToken(@Req() req: AuthenticatedRequest) {\n return {\n valid: true,\n user_id: req.user.sub,\n client_id: req.user.client_id,\n scope: req.user.scope,\n expires_at: req.user.exp! * 1000,\n };\n }\n\n validatePKCE(\n code_verifier: string,\n code_challenge: string,\n method: string,\n ): boolean {\n if (method === 'plain') {\n return code_verifier === code_challenge;\n } else if (method === 'S256') {\n const hash = createHash('sha256')\n .update(code_verifier)\n .digest('base64url');\n return hash === code_challenge;\n }\n return false;\n }\n }\n\n return McpOAuthController;\n}\n"]}
1
+ {"version":3,"file":"mcp-oauth.controller.js","sourceRoot":"","sources":["../../src/authz/mcp-oauth.controller.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BadRequestException,\n Body,\n Controller,\n Get,\n Inject,\n Logger,\n Next,\n Post,\n Query,\n Req,\n Res,\n UseGuards,\n} from '@nestjs/common';\nimport { createHash, randomBytes } from 'crypto';\nimport { Request as ExpressRequest, NextFunction, Response } from 'express';\nimport passport from 'passport';\nimport { AuthenticatedRequest, McpAuthJwtGuard } from './guards/jwt-auth.guard';\nimport {\n OAuthEndpointConfiguration,\n OAuthModuleOptions,\n OAuthSession,\n OAuthUserProfile,\n} from './providers/oauth-provider.interface';\nimport { ClientService } from './services/client.service';\nimport { JwtTokenService, TokenPair } from './services/jwt-token.service';\nimport { STRATEGY_NAME } from './services/oauth-strategy.service';\nimport {\n ClientRegistrationDto,\n IOAuthStore,\n} from './stores/oauth-store.interface';\nimport { normalizeEndpoint } from '../mcp/utils/normalize-endpoint';\n\ninterface OAuthCallbackRequest extends ExpressRequest {\n user?: {\n profile: OAuthUserProfile;\n accessToken: string;\n provider: string;\n };\n}\n\nexport function createMcpOAuthController(\n endpoints: OAuthEndpointConfiguration = {},\n) {\n @Controller()\n class McpOAuthController {\n readonly logger = new Logger(McpOAuthController.name);\n readonly serverUrl: string;\n readonly isProduction: boolean;\n readonly options: OAuthModuleOptions;\n constructor(\n @Inject('OAUTH_MODULE_OPTIONS') options: OAuthModuleOptions,\n @Inject('IOAuthStore') readonly store: IOAuthStore,\n readonly jwtTokenService: JwtTokenService,\n readonly clientService: ClientService,\n ) {\n this.serverUrl = options.serverUrl;\n this.isProduction = options.cookieSecure;\n this.options = options;\n }\n\n // OAuth endpoints\n @Get(endpoints.wellKnownAuthorizationServerMetadata)\n getAuthorizationServerMetadata() {\n return {\n issuer: this.serverUrl,\n authorization_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints.authorize}`,\n ),\n token_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints.token}`,\n ),\n registration_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints.register}`,\n ),\n response_types_supported: ['code'],\n response_modes_supported: ['query'],\n grant_types_supported: ['authorization_code', 'refresh_token'],\n token_endpoint_auth_methods_supported: [\n 'client_secret_basic',\n 'client_secret_post',\n 'none',\n ],\n scopes_supported: ['offline_access'],\n revocation_endpoint: normalizeEndpoint(\n `${this.serverUrl}/${endpoints?.revoke}`,\n ),\n code_challenge_methods_supported: ['plain', 'S256'],\n };\n }\n\n @Post(endpoints.register)\n async registerClient(@Body() registrationDto: any) {\n return await this.clientService.registerClient(registrationDto);\n }\n\n @Get(endpoints.authorize)\n async authorize(\n @Query() query: any,\n @Req()\n req: any,\n @Res() res: Response,\n @Next() next: NextFunction,\n ) {\n const {\n response_type,\n client_id,\n redirect_uri,\n code_challenge,\n code_challenge_method,\n state,\n scope,\n } = query;\n const resource = this.options.resource;\n if (response_type !== 'code') {\n throw new BadRequestException('Only response_type=code is supported');\n }\n\n if (!client_id) {\n throw new BadRequestException('Missing required parameters');\n }\n\n // Validate client and redirect URI\n const client = await this.clientService.getClient(client_id);\n if (!client) {\n throw new BadRequestException('Invalid client_id');\n }\n\n const validRedirect = await this.clientService.validateRedirectUri(\n client_id,\n redirect_uri,\n );\n if (!validRedirect) {\n throw new BadRequestException('Invalid redirect_uri');\n }\n\n // Create OAuth session\n const sessionId = randomBytes(32).toString('base64url');\n const sessionState = randomBytes(32).toString('base64url');\n\n const oauthSession: OAuthSession = {\n sessionId,\n state: sessionState,\n clientId: client_id,\n redirectUri: redirect_uri,\n codeChallenge: code_challenge,\n codeChallengeMethod: code_challenge_method || 'plain',\n oauthState: state,\n scope: scope,\n resource,\n expiresAt: Date.now() + this.options.oauthSessionExpiresIn,\n };\n\n await this.store.storeOAuthSession(sessionId, oauthSession);\n\n // Set session cookie\n res.cookie('oauth_session', sessionId, {\n httpOnly: true,\n secure: this.isProduction,\n maxAge: this.options.oauthSessionExpiresIn,\n });\n\n // Store state for passport\n res.cookie('oauth_state', sessionState, {\n httpOnly: true,\n secure: this.isProduction,\n maxAge: this.options.oauthSessionExpiresIn,\n });\n\n // Redirect to the provider's auth endpoint\n passport.authenticate(STRATEGY_NAME, {\n state: req.cookies?.oauth_state,\n })(req, res, next);\n }\n\n @Get(endpoints.callback)\n handleProviderCallback(\n @Req() req: OAuthCallbackRequest,\n @Res() res: Response,\n @Next() next: NextFunction,\n ) {\n // Use a custom callback to handle the authentication result\n passport.authenticate(\n STRATEGY_NAME,\n { session: false },\n async (err: any, user: any) => {\n try {\n if (err) {\n this.logger.error('OAuth callback error:', err);\n throw new BadRequestException('Authentication failed');\n }\n\n if (!user) {\n throw new BadRequestException('Authentication failed');\n }\n\n req.user = user;\n await this.processAuthenticationSuccess(req, res);\n } catch (error) {\n next(error);\n }\n },\n )(req, res, next);\n }\n\n async processAuthenticationSuccess(\n req: OAuthCallbackRequest,\n res: Response,\n ) {\n const user = req.user;\n if (!user) {\n throw new BadRequestException('Authentication failed');\n }\n\n const sessionId = req.cookies?.oauth_session;\n if (!sessionId) {\n throw new BadRequestException('Missing OAuth session');\n }\n\n const session = await this.store.getOAuthSession(sessionId);\n if (!session) {\n throw new BadRequestException('Invalid or expired OAuth session');\n }\n\n // Verify state\n const stateFromCookie = req.cookies?.oauth_state;\n if (session.state !== stateFromCookie) {\n throw new BadRequestException('Invalid state parameter');\n }\n\n // Generate JWT for UI access\n const jwt = this.jwtTokenService.generateUserToken(\n user.profile.username,\n user.profile,\n );\n\n // Set JWT token as cookie for UI endpoints\n res.cookie('auth_token', jwt, {\n httpOnly: true,\n secure: this.isProduction,\n maxAge: this.options.cookieMaxAge,\n });\n\n // Clear temporary cookies\n res.clearCookie('oauth_session');\n res.clearCookie('oauth_state');\n\n // Generate authorization code\n const authCode = randomBytes(32).toString('base64url');\n\n // Store the auth code\n await this.store.storeAuthCode({\n code: authCode,\n user_id: user.profile.username,\n client_id: session.clientId!,\n redirect_uri: session.redirectUri!,\n code_challenge: session.codeChallenge!,\n code_challenge_method: session.codeChallengeMethod!,\n expires_at: Date.now() + this.options.authCodeExpiresIn,\n resource: session.resource,\n scope: session.scope,\n github_access_token: '', // No longer provider-specific\n });\n\n // Build redirect URL with authorization code\n const redirectUrl = new URL(session.redirectUri!);\n redirectUrl.searchParams.set('code', authCode);\n if (session.oauthState) {\n redirectUrl.searchParams.set('state', session.oauthState);\n }\n\n // Clean up session\n await this.store.removeOAuthSession(sessionId);\n\n res.redirect(redirectUrl.toString());\n }\n\n // Token endpoints (remain the same)\n @Post(endpoints.token)\n async exchangeToken(\n @Body() body: any,\n @Req() req: any,\n ): Promise<TokenPair> {\n const {\n grant_type,\n code,\n code_verifier,\n redirect_uri,\n client_id,\n client_secret,\n refresh_token,\n } = body;\n\n if (grant_type === 'authorization_code') {\n // Extract client credentials based on authentication method\n const clientCredentials = this.extractClientCredentials(req, body);\n return this.handleAuthorizationCodeGrant(\n code,\n code_verifier,\n redirect_uri,\n clientCredentials,\n );\n } else if (grant_type === 'refresh_token') {\n // For refresh tokens, try to extract client credentials, but allow fallback to token-based extraction\n let clientCredentials: { client_id: string; client_secret?: string };\n try {\n clientCredentials = this.extractClientCredentials(req, body);\n } catch {\n // If we can't extract credentials, we'll try to get them from the refresh token\n clientCredentials = { client_id: '' }; // Will be filled from token\n }\n return this.handleRefreshTokenGrant(refresh_token, clientCredentials);\n } else {\n throw new BadRequestException('Unsupported grant_type');\n }\n }\n\n /**\n * Extract client credentials from request based on authentication method\n */\n extractClientCredentials(\n req: any,\n body: any,\n ): { client_id: string; client_secret?: string } {\n // Try client_secret_basic first (Authorization header)\n const authHeader = req.headers?.authorization;\n if (authHeader && authHeader.startsWith('Basic ')) {\n const credentials = Buffer.from(authHeader.slice(6), 'base64').toString(\n 'utf-8',\n );\n const [client_id, client_secret] = credentials.split(':', 2);\n if (client_id) {\n return { client_id, client_secret };\n }\n }\n\n // Try client_secret_post (body parameters)\n if (body.client_id) {\n return {\n client_id: body.client_id,\n client_secret: body.client_secret,\n };\n }\n\n throw new BadRequestException('Missing client credentials');\n }\n\n /**\n * Validate client authentication based on the client's configured method\n */\n validateClientAuthentication(\n client: any,\n clientCredentials: { client_id: string; client_secret?: string },\n ): void {\n if (!client) {\n throw new BadRequestException('Invalid client_id');\n }\n\n const { token_endpoint_auth_method } = client;\n\n switch (token_endpoint_auth_method) {\n case 'client_secret_basic':\n case 'client_secret_post':\n if (!clientCredentials.client_secret) {\n throw new BadRequestException(\n 'Client secret required for this authentication method',\n );\n }\n if (client.client_secret !== clientCredentials.client_secret) {\n throw new BadRequestException('Invalid client credentials');\n }\n break;\n\n case 'none':\n // Public client - no secret required\n if (clientCredentials.client_secret) {\n throw new BadRequestException(\n 'Client secret not allowed for public clients',\n );\n }\n break;\n\n default:\n throw new BadRequestException(\n `Unsupported authentication method: ${token_endpoint_auth_method}`,\n );\n }\n }\n\n async handleAuthorizationCodeGrant(\n code: string,\n code_verifier: string,\n _redirect_uri: string,\n clientCredentials: { client_id: string; client_secret?: string },\n ): Promise<TokenPair> {\n this.logger.debug('handleAuthorizationCodeGrant - Params:', {\n code,\n client_id: clientCredentials.client_id,\n });\n\n // Get and validate the authorization code\n const authCode = await this.store.getAuthCode(code);\n if (!authCode) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - Invalid authorization code:',\n code,\n );\n throw new BadRequestException('Invalid authorization code');\n }\n if (authCode.expires_at < Date.now()) {\n await this.store.removeAuthCode(code);\n this.logger.error(\n 'handleAuthorizationCodeGrant - Authorization code expired:',\n code,\n );\n throw new BadRequestException('Authorization code has expired');\n }\n if (authCode.client_id !== clientCredentials.client_id) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - Client ID mismatch:',\n { expected: authCode.client_id, got: clientCredentials.client_id },\n );\n throw new BadRequestException('Client ID mismatch');\n }\n\n // Get client and validate authentication\n const client = await this.clientService.getClient(\n clientCredentials.client_id,\n );\n this.validateClientAuthentication(client, clientCredentials);\n if (authCode.code_challenge) {\n const isValid = this.validatePKCE(\n code_verifier,\n authCode.code_challenge,\n authCode.code_challenge_method,\n );\n if (!isValid) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - Invalid PKCE verification',\n );\n throw new BadRequestException('Invalid PKCE verification');\n }\n }\n if (!authCode.resource) {\n this.logger.error(\n 'handleAuthorizationCodeGrant - No resource associated with code',\n );\n throw new BadRequestException(\n 'Authorization code is not associated with a resource',\n );\n }\n\n const tokens = this.jwtTokenService.generateTokenPair(\n authCode.user_id,\n clientCredentials.client_id,\n authCode.scope,\n authCode.resource,\n );\n await this.store.removeAuthCode(code);\n this.logger.log(\n 'handleAuthorizationCodeGrant - Token pair generated for user:',\n authCode.user_id,\n );\n return tokens;\n }\n\n async handleRefreshTokenGrant(\n refresh_token: string,\n clientCredentials: { client_id: string; client_secret?: string },\n ): Promise<TokenPair> {\n // Verify the refresh token first to get client_id from token if not provided\n const payload = this.jwtTokenService.validateToken(refresh_token);\n if (!payload || payload.type !== 'refresh') {\n throw new BadRequestException('Invalid or expired refresh token');\n }\n\n // Use client_id from token if not provided in credentials\n const clientId = clientCredentials.client_id || payload.client_id;\n if (!clientId) {\n throw new BadRequestException('Unable to determine client_id');\n }\n\n // Get client and validate authentication\n const client = await this.clientService.getClient(clientId);\n\n // For refresh token grants, we can be more lenient with client authentication\n // if the token already contains the client_id and the client is public\n if (client?.token_endpoint_auth_method !== 'none') {\n this.validateClientAuthentication(client, {\n ...clientCredentials,\n client_id: clientId,\n });\n }\n\n // Verify the refresh token belongs to the client\n if (payload.client_id !== clientId) {\n throw new BadRequestException(\n 'Invalid refresh token or token does not belong to this client',\n );\n }\n\n const newTokens = this.jwtTokenService.refreshAccessToken(refresh_token);\n if (!newTokens) {\n throw new BadRequestException('Failed to refresh token');\n }\n\n return newTokens;\n }\n\n @Get(endpoints.validate)\n @UseGuards(McpAuthJwtGuard)\n validateToken(@Req() req: AuthenticatedRequest) {\n const response: any = {\n valid: true,\n user_id: req.user.sub,\n client_id: req.user.azp || req.user.client_id, // Support both azp and client_id for backward compatibility\n expires_at: req.user.exp! * 1000,\n };\n\n // Only include scope if it exists in the token\n if (req.user.scope) {\n response.scope = req.user.scope;\n }\n\n return response;\n }\n\n validatePKCE(\n code_verifier: string,\n code_challenge: string,\n method: string,\n ): boolean {\n if (method === 'plain') {\n return code_verifier === code_challenge;\n } else if (method === 'S256') {\n const hash = createHash('sha256')\n .update(code_verifier)\n .digest('base64url');\n return hash === code_challenge;\n }\n return false;\n }\n }\n\n return McpOAuthController;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-oauth.module.d.ts","sourceRoot":"","sources":["../../src/authz/mcp-oauth.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,gBAAgB,CAAC;AAO/D,OAAO,EACL,sBAAsB,IAAI,qBAAqB,EAE/C,mBAAmB,EAEpB,MAAM,sCAAsC,CAAC;AAc9C,eAAO,MAAM,eAAe,EAAE,mBAqB7B,CAAC;AAEF,qBAEa,aAAa;IACxB,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,qBAAqB,GAAG,aAAa;IAsG7D,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAwBtC,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAiBtC,OAAO,CAAC,MAAM,CAAC,uBAAuB;IA0BtC,OAAO,CAAC,MAAM,CAAC,mBAAmB;CA+BnC"}
1
+ {"version":3,"file":"mcp-oauth.module.d.ts","sourceRoot":"","sources":["../../src/authz/mcp-oauth.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,gBAAgB,CAAC;AAO/D,OAAO,EACL,sBAAsB,IAAI,qBAAqB,EAE/C,mBAAmB,EAEpB,MAAM,sCAAsC,CAAC;AAc9C,eAAO,MAAM,eAAe,EAAE,mBAsB7B,CAAC;AAEF,qBAEa,aAAa;IACxB,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,qBAAqB,GAAG,aAAa;IAsG7D,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAwBtC,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAiBtC,OAAO,CAAC,MAAM,CAAC,uBAAuB;IA0BtC,OAAO,CAAC,MAAM,CAAC,mBAAmB;CA+BnC"}
@@ -35,7 +35,7 @@ exports.DEFAULT_OPTIONS = {
35
35
  nodeEnv: 'development',
36
36
  apiPrefix: '',
37
37
  endpoints: {
38
- wellKnown: '/.well-known/oauth-authorization-server',
38
+ wellKnownAuthorizationServerMetadata: '/.well-known/oauth-authorization-server',
39
39
  register: '/register',
40
40
  authorize: '/authorize',
41
41
  callback: '/callback',
@@ -184,7 +184,7 @@ exports.McpAuthModule = McpAuthModule = McpAuthModule_1 = __decorate([
184
184
  ], McpAuthModule);
185
185
  function prepareEndpoints(apiPrefix, defaultEndpoints, configuredEndpoints) {
186
186
  const updatedDefaultEndpoints = {
187
- wellKnown: defaultEndpoints.wellKnown,
187
+ wellKnownAuthorizationServerMetadata: defaultEndpoints.wellKnownAuthorizationServerMetadata,
188
188
  callback: (0, normalize_endpoint_1.normalizeEndpoint)(`/${apiPrefix}/${defaultEndpoints.callback}`),
189
189
  token: (0, normalize_endpoint_1.normalizeEndpoint)(`/${apiPrefix}/${defaultEndpoints.token}`),
190
190
  validate: (0, normalize_endpoint_1.normalizeEndpoint)(`/${apiPrefix}/${defaultEndpoints.validate}`),
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-oauth.module.js","sourceRoot":"","sources":["../../src/authz/mcp-oauth.module.ts"],"names":[],"mappings":"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","sourcesContent":["import { DynamicModule, Global, Module } from '@nestjs/common';\nimport { ConfigModule } from '@nestjs/config';\nimport { JwtModule } from '@nestjs/jwt';\nimport { PassportModule } from '@nestjs/passport';\nimport { TypeOrmModule } from '@nestjs/typeorm';\nimport { McpAuthJwtGuard } from './guards/jwt-auth.guard';\nimport { createMcpOAuthController } from './mcp-oauth.controller';\nimport {\n OAuthUserModuleOptions as AuthUserModuleOptions,\n OAuthEndpointConfiguration,\n OAuthModuleDefaults,\n OAuthModuleOptions,\n} from './providers/oauth-provider.interface';\nimport { ClientService } from './services/client.service';\nimport { JwtTokenService } from './services/jwt-token.service';\nimport { OAuthStrategyService } from './services/oauth-strategy.service';\nimport { MemoryStore } from './stores/memory-store.service';\nimport {\n AuthorizationCodeEntity,\n OAuthClientEntity,\n OAuthSessionEntity,\n} from './stores/typeorm/entities';\nimport { TypeOrmStore } from './stores/typeorm/typeorm-store.service';\nimport { normalizeEndpoint } from '../mcp/utils/normalize-endpoint';\n\n// Default configuration values\nexport const DEFAULT_OPTIONS: OAuthModuleDefaults = {\n serverUrl: 'https://localhost:3000',\n resource: 'https://localhost:3000/mcp',\n jwtIssuer: 'https://localhost:3000',\n jwtAudience: 'mcp-client',\n jwtAccessTokenExpiresIn: '60s',\n jwtRefreshTokenExpiresIn: '30d',\n cookieMaxAge: 24 * 60 * 60 * 1000, // 24 hours\n oauthSessionExpiresIn: 10 * 60 * 1000, // 10 minutes\n authCodeExpiresIn: 10 * 60 * 1000, // 10 minutes\n nodeEnv: 'development',\n apiPrefix: '',\n endpoints: {\n wellKnown: '/.well-known/oauth-authorization-server',\n register: '/register',\n authorize: '/authorize',\n callback: '/callback',\n token: '/token',\n validate: '/validate',\n revoke: '/revoke',\n },\n};\n\n@Global()\n@Module({})\nexport class McpAuthModule {\n static forRoot(options: AuthUserModuleOptions): DynamicModule {\n // Merge user options with defaults and validate\n const resolvedOptions = this.mergeAndValidateOptions(\n DEFAULT_OPTIONS,\n options,\n );\n\n resolvedOptions.endpoints = prepareEndpoints(\n resolvedOptions.apiPrefix,\n DEFAULT_OPTIONS.endpoints,\n options.endpoints || {},\n );\n const oauthModuleOptions = {\n provide: 'OAUTH_MODULE_OPTIONS',\n useValue: resolvedOptions,\n };\n\n // Determine imports based on configuration\n const imports = [\n ConfigModule,\n PassportModule.register({\n defaultStrategy: 'jwt',\n session: false,\n }),\n JwtModule.register({\n secret: resolvedOptions.jwtSecret,\n signOptions: {\n issuer: resolvedOptions.jwtIssuer,\n audience: resolvedOptions.jwtAudience,\n },\n }),\n ];\n\n // Add TypeORM configuration if using TypeORM store\n const storeConfig = resolvedOptions.storeConfiguration;\n const isTypeOrmStore = storeConfig?.type === 'typeorm';\n if (storeConfig && storeConfig.type === 'typeorm') {\n const typeormOptions = storeConfig.options;\n imports.push(\n TypeOrmModule.forRoot({\n ...typeormOptions,\n entities: [\n ...((typeormOptions.entities || []) as any[]),\n OAuthClientEntity,\n AuthorizationCodeEntity,\n OAuthSessionEntity,\n ],\n }),\n TypeOrmModule.forFeature([\n OAuthClientEntity,\n AuthorizationCodeEntity,\n OAuthSessionEntity,\n ]),\n );\n }\n\n // Create store provider based on configuration\n const oauthStoreProvider = this.createStoreProvider(\n resolvedOptions.storeConfiguration,\n );\n\n // Create alias for compatibility with injection\n const oauthStoreAliasProvider = {\n provide: MemoryStore,\n useExisting: 'IOAuthStore',\n };\n\n const providers: any[] = [\n oauthModuleOptions,\n oauthStoreProvider,\n oauthStoreAliasProvider,\n OAuthStrategyService,\n ClientService,\n JwtTokenService,\n McpAuthJwtGuard,\n ];\n\n // Add TypeOrmStore to providers if using TypeORM\n if (isTypeOrmStore) {\n providers.push(TypeOrmStore);\n }\n\n // Create controller with apiPrefix\n const OAuthControllerClass = createMcpOAuthController(\n resolvedOptions.endpoints,\n );\n\n return {\n module: McpAuthModule,\n imports,\n controllers: [OAuthControllerClass],\n providers,\n exports: [\n JwtTokenService,\n 'IOAuthStore',\n MemoryStore,\n McpAuthJwtGuard,\n OAuthStrategyService,\n ],\n };\n }\n\n private static mergeAndValidateOptions(\n defaults: OAuthModuleDefaults,\n options: AuthUserModuleOptions,\n ): OAuthModuleOptions {\n // Validate required options first\n this.validateRequiredOptions(options);\n\n // Merge with defaults\n const resolvedOptions: OAuthModuleOptions = {\n ...defaults,\n ...options,\n // Ensure jwtIssuer defaults to serverUrl if not provided\n jwtIssuer:\n options.jwtIssuer || options.serverUrl || DEFAULT_OPTIONS.jwtIssuer,\n cookieSecure:\n options.cookieSecure || process.env.NODE_ENV === 'production',\n };\n\n // Final validation of resolved options\n this.validateResolvedOptions(resolvedOptions);\n\n return resolvedOptions;\n }\n\n private static validateRequiredOptions(options: AuthUserModuleOptions): void {\n const requiredFields: (keyof AuthUserModuleOptions)[] = [\n 'provider',\n 'clientId',\n 'clientSecret',\n 'jwtSecret',\n ];\n\n for (const field of requiredFields) {\n if (!options[field]) {\n throw new Error(\n `OAuthModuleOptions: ${String(field)} is required and must be provided by the user`,\n );\n }\n }\n }\n\n private static validateResolvedOptions(options: OAuthModuleOptions): void {\n // Validate JWT secret is strong enough\n if (options.jwtSecret.length < 32) {\n throw new Error(\n 'OAuthModuleOptions: jwtSecret must be at least 32 characters long',\n );\n }\n\n // Validate URLs are proper format\n try {\n new URL(options.serverUrl);\n new URL(options.jwtIssuer);\n } catch (error) {\n throw new Error(\n 'OAuthModuleOptions: serverUrl and jwtIssuer must be valid URLs',\n );\n }\n\n // Validate provider configuration\n if (!options.provider.name || !options.provider.strategy) {\n throw new Error(\n 'OAuthModuleOptions: provider must have name and strategy',\n );\n }\n }\n\n private static createStoreProvider(\n storeConfiguration: OAuthModuleOptions['storeConfiguration'],\n ) {\n if (!storeConfiguration || storeConfiguration.type === 'memory') {\n // Default memory store\n return {\n provide: 'IOAuthStore',\n useValue: new MemoryStore(),\n };\n }\n\n if (storeConfiguration.type === 'typeorm') {\n // TypeORM store\n return {\n provide: 'IOAuthStore',\n useClass: TypeOrmStore,\n };\n }\n\n if (storeConfiguration.type === 'custom') {\n // Custom store\n return {\n provide: 'IOAuthStore',\n useValue: storeConfiguration.store,\n };\n }\n\n throw new Error(\n `Unknown store configuration type: ${(storeConfiguration as any).type}`,\n );\n }\n}\n\nfunction prepareEndpoints(\n apiPrefix: string,\n defaultEndpoints: OAuthEndpointConfiguration,\n configuredEndpoints: OAuthEndpointConfiguration,\n) {\n const updatedDefaultEndpoints = {\n wellKnown: defaultEndpoints.wellKnown,\n callback: normalizeEndpoint(`/${apiPrefix}/${defaultEndpoints.callback}`),\n token: normalizeEndpoint(`/${apiPrefix}/${defaultEndpoints.token}`),\n validate: normalizeEndpoint(`/${apiPrefix}/${defaultEndpoints.validate}`),\n revoke: normalizeEndpoint(`/${apiPrefix}/${defaultEndpoints.revoke}`),\n authorize: normalizeEndpoint(`/${apiPrefix}/${defaultEndpoints.authorize}`),\n register: normalizeEndpoint(`/${apiPrefix}/${defaultEndpoints.register}`),\n } as OAuthEndpointConfiguration;\n\n return {\n ...updatedDefaultEndpoints,\n ...configuredEndpoints,\n };\n}\n"]}
1
+ {"version":3,"file":"mcp-oauth.module.js","sourceRoot":"","sources":["../../src/authz/mcp-oauth.module.ts"],"names":[],"mappings":"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","sourcesContent":["import { DynamicModule, Global, Module } from '@nestjs/common';\nimport { ConfigModule } from '@nestjs/config';\nimport { JwtModule } from '@nestjs/jwt';\nimport { PassportModule } from '@nestjs/passport';\nimport { TypeOrmModule } from '@nestjs/typeorm';\nimport { McpAuthJwtGuard } from './guards/jwt-auth.guard';\nimport { createMcpOAuthController } from './mcp-oauth.controller';\nimport {\n OAuthUserModuleOptions as AuthUserModuleOptions,\n OAuthEndpointConfiguration,\n OAuthModuleDefaults,\n OAuthModuleOptions,\n} from './providers/oauth-provider.interface';\nimport { ClientService } from './services/client.service';\nimport { JwtTokenService } from './services/jwt-token.service';\nimport { OAuthStrategyService } from './services/oauth-strategy.service';\nimport { MemoryStore } from './stores/memory-store.service';\nimport {\n AuthorizationCodeEntity,\n OAuthClientEntity,\n OAuthSessionEntity,\n} from './stores/typeorm/entities';\nimport { TypeOrmStore } from './stores/typeorm/typeorm-store.service';\nimport { normalizeEndpoint } from '../mcp/utils/normalize-endpoint';\n\n// Default configuration values\nexport const DEFAULT_OPTIONS: OAuthModuleDefaults = {\n serverUrl: 'https://localhost:3000',\n resource: 'https://localhost:3000/mcp',\n jwtIssuer: 'https://localhost:3000',\n jwtAudience: 'mcp-client',\n jwtAccessTokenExpiresIn: '60s',\n jwtRefreshTokenExpiresIn: '30d',\n cookieMaxAge: 24 * 60 * 60 * 1000, // 24 hours\n oauthSessionExpiresIn: 10 * 60 * 1000, // 10 minutes\n authCodeExpiresIn: 10 * 60 * 1000, // 10 minutes\n nodeEnv: 'development',\n apiPrefix: '',\n endpoints: {\n wellKnownAuthorizationServerMetadata:\n '/.well-known/oauth-authorization-server',\n register: '/register',\n authorize: '/authorize',\n callback: '/callback',\n token: '/token',\n validate: '/validate',\n revoke: '/revoke',\n },\n};\n\n@Global()\n@Module({})\nexport class McpAuthModule {\n static forRoot(options: AuthUserModuleOptions): DynamicModule {\n // Merge user options with defaults and validate\n const resolvedOptions = this.mergeAndValidateOptions(\n DEFAULT_OPTIONS,\n options,\n );\n\n resolvedOptions.endpoints = prepareEndpoints(\n resolvedOptions.apiPrefix,\n DEFAULT_OPTIONS.endpoints,\n options.endpoints || {},\n );\n const oauthModuleOptions = {\n provide: 'OAUTH_MODULE_OPTIONS',\n useValue: resolvedOptions,\n };\n\n // Determine imports based on configuration\n const imports = [\n ConfigModule,\n PassportModule.register({\n defaultStrategy: 'jwt',\n session: false,\n }),\n JwtModule.register({\n secret: resolvedOptions.jwtSecret,\n signOptions: {\n issuer: resolvedOptions.jwtIssuer,\n audience: resolvedOptions.jwtAudience,\n },\n }),\n ];\n\n // Add TypeORM configuration if using TypeORM store\n const storeConfig = resolvedOptions.storeConfiguration;\n const isTypeOrmStore = storeConfig?.type === 'typeorm';\n if (storeConfig && storeConfig.type === 'typeorm') {\n const typeormOptions = storeConfig.options;\n imports.push(\n TypeOrmModule.forRoot({\n ...typeormOptions,\n entities: [\n ...((typeormOptions.entities || []) as any[]),\n OAuthClientEntity,\n AuthorizationCodeEntity,\n OAuthSessionEntity,\n ],\n }),\n TypeOrmModule.forFeature([\n OAuthClientEntity,\n AuthorizationCodeEntity,\n OAuthSessionEntity,\n ]),\n );\n }\n\n // Create store provider based on configuration\n const oauthStoreProvider = this.createStoreProvider(\n resolvedOptions.storeConfiguration,\n );\n\n // Create alias for compatibility with injection\n const oauthStoreAliasProvider = {\n provide: MemoryStore,\n useExisting: 'IOAuthStore',\n };\n\n const providers: any[] = [\n oauthModuleOptions,\n oauthStoreProvider,\n oauthStoreAliasProvider,\n OAuthStrategyService,\n ClientService,\n JwtTokenService,\n McpAuthJwtGuard,\n ];\n\n // Add TypeOrmStore to providers if using TypeORM\n if (isTypeOrmStore) {\n providers.push(TypeOrmStore);\n }\n\n // Create controller with apiPrefix\n const OAuthControllerClass = createMcpOAuthController(\n resolvedOptions.endpoints,\n );\n\n return {\n module: McpAuthModule,\n imports,\n controllers: [OAuthControllerClass],\n providers,\n exports: [\n JwtTokenService,\n 'IOAuthStore',\n MemoryStore,\n McpAuthJwtGuard,\n OAuthStrategyService,\n ],\n };\n }\n\n private static mergeAndValidateOptions(\n defaults: OAuthModuleDefaults,\n options: AuthUserModuleOptions,\n ): OAuthModuleOptions {\n // Validate required options first\n this.validateRequiredOptions(options);\n\n // Merge with defaults\n const resolvedOptions: OAuthModuleOptions = {\n ...defaults,\n ...options,\n // Ensure jwtIssuer defaults to serverUrl if not provided\n jwtIssuer:\n options.jwtIssuer || options.serverUrl || DEFAULT_OPTIONS.jwtIssuer,\n cookieSecure:\n options.cookieSecure || process.env.NODE_ENV === 'production',\n };\n\n // Final validation of resolved options\n this.validateResolvedOptions(resolvedOptions);\n\n return resolvedOptions;\n }\n\n private static validateRequiredOptions(options: AuthUserModuleOptions): void {\n const requiredFields: (keyof AuthUserModuleOptions)[] = [\n 'provider',\n 'clientId',\n 'clientSecret',\n 'jwtSecret',\n ];\n\n for (const field of requiredFields) {\n if (!options[field]) {\n throw new Error(\n `OAuthModuleOptions: ${String(field)} is required and must be provided by the user`,\n );\n }\n }\n }\n\n private static validateResolvedOptions(options: OAuthModuleOptions): void {\n // Validate JWT secret is strong enough\n if (options.jwtSecret.length < 32) {\n throw new Error(\n 'OAuthModuleOptions: jwtSecret must be at least 32 characters long',\n );\n }\n\n // Validate URLs are proper format\n try {\n new URL(options.serverUrl);\n new URL(options.jwtIssuer);\n } catch (error) {\n throw new Error(\n 'OAuthModuleOptions: serverUrl and jwtIssuer must be valid URLs',\n );\n }\n\n // Validate provider configuration\n if (!options.provider.name || !options.provider.strategy) {\n throw new Error(\n 'OAuthModuleOptions: provider must have name and strategy',\n );\n }\n }\n\n private static createStoreProvider(\n storeConfiguration: OAuthModuleOptions['storeConfiguration'],\n ) {\n if (!storeConfiguration || storeConfiguration.type === 'memory') {\n // Default memory store\n return {\n provide: 'IOAuthStore',\n useValue: new MemoryStore(),\n };\n }\n\n if (storeConfiguration.type === 'typeorm') {\n // TypeORM store\n return {\n provide: 'IOAuthStore',\n useClass: TypeOrmStore,\n };\n }\n\n if (storeConfiguration.type === 'custom') {\n // Custom store\n return {\n provide: 'IOAuthStore',\n useValue: storeConfiguration.store,\n };\n }\n\n throw new Error(\n `Unknown store configuration type: ${(storeConfiguration as any).type}`,\n );\n }\n}\n\nfunction prepareEndpoints(\n apiPrefix: string,\n defaultEndpoints: OAuthEndpointConfiguration,\n configuredEndpoints: OAuthEndpointConfiguration,\n) {\n const updatedDefaultEndpoints = {\n wellKnownAuthorizationServerMetadata:\n defaultEndpoints.wellKnownAuthorizationServerMetadata,\n callback: normalizeEndpoint(`/${apiPrefix}/${defaultEndpoints.callback}`),\n token: normalizeEndpoint(`/${apiPrefix}/${defaultEndpoints.token}`),\n validate: normalizeEndpoint(`/${apiPrefix}/${defaultEndpoints.validate}`),\n revoke: normalizeEndpoint(`/${apiPrefix}/${defaultEndpoints.revoke}`),\n authorize: normalizeEndpoint(`/${apiPrefix}/${defaultEndpoints.authorize}`),\n register: normalizeEndpoint(`/${apiPrefix}/${defaultEndpoints.register}`),\n } as OAuthEndpointConfiguration;\n\n return {\n ...updatedDefaultEndpoints,\n ...configuredEndpoints,\n };\n}\n"]}
@@ -0,0 +1,48 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ import { AuthenticatedRequest } from './guards/jwt-auth.guard';
3
+ import { OAuthModuleOptions, OAuthUserProfile } from './providers/oauth-provider.interface';
4
+ import { ClientService } from './services/client.service';
5
+ import { JwtTokenService } from './services/jwt-token.service';
6
+ import { IOAuthStore } from './stores/oauth-store.interface';
7
+ interface GitHubAuthRequest extends Request {
8
+ user?: {
9
+ profile: OAuthUserProfile;
10
+ accessToken: string;
11
+ provider: string;
12
+ };
13
+ }
14
+ export declare class OidcProviderController {
15
+ private readonly oidcProvider;
16
+ private readonly options;
17
+ private readonly store;
18
+ private readonly jwtTokenService;
19
+ private readonly clientService;
20
+ private readonly logger;
21
+ constructor(oidcProvider: any, options: OAuthModuleOptions, store: IOAuthStore, jwtTokenService: JwtTokenService, clientService: ClientService);
22
+ handleInteraction(uid: string, req: Request, res: Response, next: NextFunction): Promise<void>;
23
+ handleGitHubCallback(req: GitHubAuthRequest, res: Response, next: NextFunction): void;
24
+ private completeOidcInteraction;
25
+ findAccount(_ctx: any, id: string): Promise<{
26
+ accountId: string;
27
+ claims(): Promise<{
28
+ sub: string;
29
+ }>;
30
+ }>;
31
+ registerClient(registrationDto: any): Promise<import("./stores/oauth-store.interface").OAuthClient>;
32
+ validateToken(req: AuthenticatedRequest): {
33
+ active: boolean;
34
+ sub: string;
35
+ client_id: string | undefined;
36
+ scope: string | undefined;
37
+ exp: number | undefined;
38
+ iat: number | undefined;
39
+ token_type: string;
40
+ };
41
+ getHealth(): {
42
+ status: string;
43
+ service: string;
44
+ timestamp: string;
45
+ };
46
+ }
47
+ export {};
48
+ //# sourceMappingURL=oidc-provider.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc-provider.controller.d.ts","sourceRoot":"","sources":["../../src/authz/oidc-provider.controller.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG1D,OAAO,EAAE,oBAAoB,EAAmB,MAAM,yBAAyB,CAAC;AAChF,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAE7D,UAAU,iBAAkB,SAAQ,OAAO;IACzC,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,gBAAgB,CAAC;QAC1B,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,qBACa,sBAAsB;IAIT,OAAO,CAAC,QAAQ,CAAC,YAAY;IAEnD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACD,OAAO,CAAC,QAAQ,CAAC,KAAK;IAC7C,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa;IARhC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;gBAGzB,YAAY,EAAE,GAAG,EAEvC,OAAO,EAAE,kBAAkB,EACJ,KAAK,EAAE,WAAW,EACzC,eAAe,EAAE,eAAe,EAChC,aAAa,EAAE,aAAa;IAQzC,iBAAiB,CACP,GAAG,EAAE,MAAM,EAClB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACZ,IAAI,EAAE,YAAY;IA4B5B,oBAAoB,CACX,GAAG,EAAE,iBAAiB,EACtB,GAAG,EAAE,QAAQ,EACZ,IAAI,EAAE,YAAY;YA4Bd,uBAAuB;IA6D/B,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM;;;;;;IAkBjC,cAAc,CAAS,eAAe,EAAE,GAAG;IASjD,aAAa,CAAQ,GAAG,EAAE,oBAAoB;;;;;;;;;IAgB9C,SAAS;;;;;CAOV"}
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ var OidcProviderController_1;
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.OidcProviderController = void 0;
20
+ const common_1 = require("@nestjs/common");
21
+ const nest_oidc_provider_1 = require("nest-oidc-provider");
22
+ const passport_1 = __importDefault(require("passport"));
23
+ const jwt_auth_guard_1 = require("./guards/jwt-auth.guard");
24
+ const client_service_1 = require("./services/client.service");
25
+ const jwt_token_service_1 = require("./services/jwt-token.service");
26
+ const oauth_strategy_service_1 = require("./services/oauth-strategy.service");
27
+ let OidcProviderController = OidcProviderController_1 = class OidcProviderController {
28
+ constructor(oidcProvider, options, store, jwtTokenService, clientService) {
29
+ this.oidcProvider = oidcProvider;
30
+ this.options = options;
31
+ this.store = store;
32
+ this.jwtTokenService = jwtTokenService;
33
+ this.clientService = clientService;
34
+ this.logger = new common_1.Logger(OidcProviderController_1.name);
35
+ }
36
+ async handleInteraction(uid, req, res, next) {
37
+ try {
38
+ const details = await this.oidcProvider.interactionDetails(req, res);
39
+ this.logger.debug('OIDC Interaction details:', details);
40
+ req.session = req.session || {};
41
+ req.session.interactionUid = uid;
42
+ req.session.interactionDetails = details;
43
+ passport_1.default.authenticate(oauth_strategy_service_1.STRATEGY_NAME, {
44
+ state: uid,
45
+ })(req, res, next);
46
+ }
47
+ catch (error) {
48
+ this.logger.error('Interaction error:', error);
49
+ throw new common_1.BadRequestException('Failed to handle interaction');
50
+ }
51
+ }
52
+ handleGitHubCallback(req, res, next) {
53
+ passport_1.default.authenticate(oauth_strategy_service_1.STRATEGY_NAME, { session: false }, async (err, user) => {
54
+ try {
55
+ if (err) {
56
+ this.logger.error('GitHub callback error:', err);
57
+ throw new common_1.BadRequestException('GitHub authentication failed');
58
+ }
59
+ if (!user) {
60
+ throw new common_1.BadRequestException('GitHub authentication failed');
61
+ }
62
+ req.user = user;
63
+ await this.completeOidcInteraction(req, res);
64
+ }
65
+ catch (error) {
66
+ next(error);
67
+ }
68
+ })(req, res, next);
69
+ }
70
+ async completeOidcInteraction(req, res) {
71
+ const user = req.user;
72
+ if (!user) {
73
+ throw new common_1.BadRequestException('No authenticated user');
74
+ }
75
+ const session = req.session;
76
+ const interactionUid = session?.interactionUid;
77
+ const interactionDetails = session?.interactionDetails;
78
+ if (!interactionUid || !interactionDetails) {
79
+ throw new common_1.BadRequestException('Missing interaction details');
80
+ }
81
+ try {
82
+ const account = {
83
+ accountId: user.profile.username,
84
+ profile: {
85
+ sub: user.profile.username,
86
+ name: user.profile.displayName || user.profile.username,
87
+ preferred_username: user.profile.username,
88
+ email: user.profile.email,
89
+ email_verified: true,
90
+ },
91
+ };
92
+ const result = {
93
+ login: {
94
+ accountId: account.accountId,
95
+ ts: Math.floor(Date.now() / 1000),
96
+ },
97
+ consent: {
98
+ grantId: interactionDetails.grantId,
99
+ },
100
+ };
101
+ await this.oidcProvider.interactionFinished(req, res, result, {
102
+ mergeWithLastSubmission: false,
103
+ });
104
+ delete session.interactionUid;
105
+ delete session.interactionDetails;
106
+ this.logger.log('OIDC interaction completed for user:', user.profile.username);
107
+ }
108
+ catch (error) {
109
+ this.logger.error('Failed to complete OIDC interaction:', error);
110
+ throw new common_1.BadRequestException('Failed to complete authentication');
111
+ }
112
+ }
113
+ async findAccount(_ctx, id) {
114
+ return {
115
+ accountId: id,
116
+ async claims() {
117
+ return {
118
+ sub: id,
119
+ };
120
+ },
121
+ };
122
+ }
123
+ async registerClient(registrationDto) {
124
+ return await this.clientService.registerClient(registrationDto);
125
+ }
126
+ validateToken(req) {
127
+ return {
128
+ active: true,
129
+ sub: req.user.sub,
130
+ client_id: req.user.client_id,
131
+ scope: req.user.scope,
132
+ exp: req.user.exp,
133
+ iat: req.user.iat,
134
+ token_type: 'Bearer',
135
+ };
136
+ }
137
+ getHealth() {
138
+ return {
139
+ status: 'ok',
140
+ service: 'oidc-provider',
141
+ timestamp: new Date().toISOString(),
142
+ };
143
+ }
144
+ };
145
+ exports.OidcProviderController = OidcProviderController;
146
+ __decorate([
147
+ (0, common_1.Get)('interaction/:uid'),
148
+ __param(0, (0, common_1.Query)('uid')),
149
+ __param(1, (0, common_1.Req)()),
150
+ __param(2, (0, common_1.Res)()),
151
+ __param(3, (0, common_1.Next)()),
152
+ __metadata("design:type", Function),
153
+ __metadata("design:paramtypes", [String, Object, Object, Function]),
154
+ __metadata("design:returntype", Promise)
155
+ ], OidcProviderController.prototype, "handleInteraction", null);
156
+ __decorate([
157
+ (0, common_1.Get)('callback'),
158
+ __param(0, (0, common_1.Req)()),
159
+ __param(1, (0, common_1.Res)()),
160
+ __param(2, (0, common_1.Next)()),
161
+ __metadata("design:type", Function),
162
+ __metadata("design:paramtypes", [Object, Object, Function]),
163
+ __metadata("design:returntype", void 0)
164
+ ], OidcProviderController.prototype, "handleGitHubCallback", null);
165
+ __decorate([
166
+ (0, common_1.Post)('reg'),
167
+ __param(0, (0, common_1.Body)()),
168
+ __metadata("design:type", Function),
169
+ __metadata("design:paramtypes", [Object]),
170
+ __metadata("design:returntype", Promise)
171
+ ], OidcProviderController.prototype, "registerClient", null);
172
+ __decorate([
173
+ (0, common_1.Post)('introspect'),
174
+ (0, common_1.UseGuards)(jwt_auth_guard_1.McpAuthJwtGuard),
175
+ __param(0, (0, common_1.Req)()),
176
+ __metadata("design:type", Function),
177
+ __metadata("design:paramtypes", [Object]),
178
+ __metadata("design:returntype", void 0)
179
+ ], OidcProviderController.prototype, "validateToken", null);
180
+ __decorate([
181
+ (0, common_1.Get)('health'),
182
+ __metadata("design:type", Function),
183
+ __metadata("design:paramtypes", []),
184
+ __metadata("design:returntype", void 0)
185
+ ], OidcProviderController.prototype, "getHealth", null);
186
+ exports.OidcProviderController = OidcProviderController = OidcProviderController_1 = __decorate([
187
+ (0, common_1.Controller)('oidc'),
188
+ __param(0, (0, nest_oidc_provider_1.InjectOidcProvider)()),
189
+ __param(1, (0, common_1.Inject)('OAUTH_MODULE_OPTIONS')),
190
+ __param(2, (0, common_1.Inject)('IOAuthStore')),
191
+ __metadata("design:paramtypes", [Object, Object, Object, jwt_token_service_1.JwtTokenService,
192
+ client_service_1.ClientService])
193
+ ], OidcProviderController);
194
+ //# sourceMappingURL=oidc-provider.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc-provider.controller.js","sourceRoot":"","sources":["../../src/authz/oidc-provider.controller.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Controller,\n Get,\n Post,\n Req,\n Res,\n Next,\n Query,\n Body,\n UseGuards,\n Inject,\n Logger,\n BadRequestException,\n} from '@nestjs/common';\nimport { Request, Response, NextFunction } from 'express';\nimport { InjectOidcProvider } from 'nest-oidc-provider';\nimport passport from 'passport';\nimport { AuthenticatedRequest, McpAuthJwtGuard } from './guards/jwt-auth.guard';\nimport {\n OAuthModuleOptions,\n OAuthUserProfile,\n} from './providers/oauth-provider.interface';\nimport { ClientService } from './services/client.service';\nimport { JwtTokenService } from './services/jwt-token.service';\nimport { STRATEGY_NAME } from './services/oauth-strategy.service';\nimport { IOAuthStore } from './stores/oauth-store.interface';\n\ninterface GitHubAuthRequest extends Request {\n user?: {\n profile: OAuthUserProfile;\n accessToken: string;\n provider: string;\n };\n}\n\n@Controller('oidc')\nexport class OidcProviderController {\n private readonly logger = new Logger(OidcProviderController.name);\n\n constructor(\n @InjectOidcProvider() private readonly oidcProvider: any,\n @Inject('OAUTH_MODULE_OPTIONS')\n private readonly options: OAuthModuleOptions,\n @Inject('IOAuthStore') private readonly store: IOAuthStore,\n private readonly jwtTokenService: JwtTokenService,\n private readonly clientService: ClientService,\n ) {}\n\n /**\n * Custom interaction endpoint for GitHub authentication\n * This replaces the default OIDC provider interaction flow\n */\n @Get('interaction/:uid')\n async handleInteraction(\n @Query('uid') uid: string,\n @Req() req: Request,\n @Res() res: Response,\n @Next() next: NextFunction,\n ) {\n try {\n // Get interaction details from OIDC provider\n const details = await this.oidcProvider.interactionDetails(req, res);\n\n this.logger.debug('OIDC Interaction details:', details);\n\n // Store interaction details in session for callback\n req.session = req.session || {};\n (req.session as any).interactionUid = uid;\n (req.session as any).interactionDetails = details;\n\n // Redirect to GitHub authentication\n passport.authenticate(STRATEGY_NAME, {\n state: uid, // Use interaction UID as state\n })(req, res, next);\n } catch (error) {\n this.logger.error('Interaction error:', error);\n throw new BadRequestException('Failed to handle interaction');\n }\n }\n\n /**\n * GitHub OAuth callback - handles GitHub authentication result\n * and completes OIDC interaction\n */\n @Get('callback')\n handleGitHubCallback(\n @Req() req: GitHubAuthRequest,\n @Res() res: Response,\n @Next() next: NextFunction,\n ) {\n passport.authenticate(\n STRATEGY_NAME,\n { session: false },\n async (err: any, user: any) => {\n try {\n if (err) {\n this.logger.error('GitHub callback error:', err);\n throw new BadRequestException('GitHub authentication failed');\n }\n\n if (!user) {\n throw new BadRequestException('GitHub authentication failed');\n }\n\n req.user = user;\n await this.completeOidcInteraction(req, res);\n } catch (error) {\n next(error);\n }\n },\n )(req, res, next);\n }\n\n /**\n * Complete OIDC interaction after successful GitHub authentication\n */\n private async completeOidcInteraction(req: GitHubAuthRequest, res: Response) {\n const user = req.user;\n if (!user) {\n throw new BadRequestException('No authenticated user');\n }\n\n const session = req.session as any;\n const interactionUid = session?.interactionUid;\n const interactionDetails = session?.interactionDetails;\n\n if (!interactionUid || !interactionDetails) {\n throw new BadRequestException('Missing interaction details');\n }\n\n try {\n // Create account representation for OIDC provider\n const account = {\n accountId: user.profile.username,\n profile: {\n sub: user.profile.username,\n name: user.profile.displayName || user.profile.username,\n preferred_username: user.profile.username,\n email: user.profile.email,\n email_verified: true,\n },\n };\n\n // Submit interaction result to OIDC provider\n const result = {\n login: {\n accountId: account.accountId,\n ts: Math.floor(Date.now() / 1000),\n },\n consent: {\n grantId: interactionDetails.grantId,\n },\n };\n\n // Complete the OIDC interaction\n await this.oidcProvider.interactionFinished(req, res, result, {\n mergeWithLastSubmission: false,\n });\n\n // Clear session data\n delete session.interactionUid;\n delete session.interactionDetails;\n\n this.logger.log(\n 'OIDC interaction completed for user:',\n user.profile.username,\n );\n } catch (error) {\n this.logger.error('Failed to complete OIDC interaction:', error);\n throw new BadRequestException('Failed to complete authentication');\n }\n }\n\n /**\n * Account lookup for OIDC provider\n * This method is called by the OIDC provider to find account information\n */\n async findAccount(_ctx: any, id: string) {\n // In a real implementation, you might want to fetch this from your user store\n // For now, we'll create a minimal account representation\n return {\n accountId: id,\n async claims() {\n return {\n sub: id,\n // Additional claims would be populated here based on your requirements\n };\n },\n };\n }\n\n /**\n * Client validation endpoint for dynamic client registration\n */\n @Post('reg')\n async registerClient(@Body() registrationDto: any) {\n return await this.clientService.registerClient(registrationDto);\n }\n\n /**\n * Token validation endpoint (introspection)\n */\n @Post('introspect')\n @UseGuards(McpAuthJwtGuard)\n validateToken(@Req() req: AuthenticatedRequest) {\n return {\n active: true,\n sub: req.user.sub,\n client_id: req.user.client_id,\n scope: req.user.scope,\n exp: req.user.exp,\n iat: req.user.iat,\n token_type: 'Bearer',\n };\n }\n\n /**\n * Health check endpoint for the OIDC provider\n */\n @Get('health')\n getHealth() {\n return {\n status: 'ok',\n service: 'oidc-provider',\n timestamp: new Date().toISOString(),\n };\n }\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { OAuthUserModuleOptions as AuthUserModuleOptions, OAuthModuleDefaults } from './providers/oauth-provider.interface';
3
+ export declare const DEFAULT_OIDC_OPTIONS: OAuthModuleDefaults;
4
+ export declare class McpOidcProviderModule {
5
+ static forRoot(options: AuthUserModuleOptions): DynamicModule;
6
+ private static mergeAndValidateOptions;
7
+ private static validateRequiredOptions;
8
+ private static validateResolvedOptions;
9
+ private static createStoreProvider;
10
+ }
11
+ //# sourceMappingURL=oidc-provider.module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc-provider.module.d.ts","sourceRoot":"","sources":["../../src/authz/oidc-provider.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,gBAAgB,CAAC;AAO/D,OAAO,EACL,sBAAsB,IAAI,qBAAqB,EAC/C,mBAAmB,EAEpB,MAAM,sCAAsC,CAAC;AAkB9C,eAAO,MAAM,oBAAoB,EAAE,mBAsBlC,CAAC;AAEF,qBAEa,qBAAqB;IAChC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,qBAAqB,GAAG,aAAa;IA6L7D,OAAO,CAAC,MAAM,CAAC,uBAAuB;IA0BtC,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAiBtC,OAAO,CAAC,MAAM,CAAC,uBAAuB;IA0BtC,OAAO,CAAC,MAAM,CAAC,mBAAmB;CA+BnC"}