@rekog/mcp-nest 1.7.0-alpha.0 → 1.7.0-alpha.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 (104) hide show
  1. package/dist/authz/guards/jwt-auth.guard.d.ts +13 -0
  2. package/dist/authz/guards/jwt-auth.guard.d.ts.map +1 -0
  3. package/dist/authz/guards/jwt-auth.guard.js +46 -0
  4. package/dist/authz/guards/jwt-auth.guard.js.map +1 -0
  5. package/dist/authz/index.d.ts +8 -1
  6. package/dist/authz/index.d.ts.map +1 -1
  7. package/dist/authz/index.js +22 -0
  8. package/dist/authz/index.js.map +1 -1
  9. package/dist/authz/interfaces/index.d.ts +3 -0
  10. package/dist/authz/interfaces/index.d.ts.map +1 -0
  11. package/dist/authz/interfaces/index.js +19 -0
  12. package/dist/authz/interfaces/index.js.map +1 -0
  13. package/dist/authz/mcp-oauth.controller.d.ts +53 -0
  14. package/dist/authz/mcp-oauth.controller.d.ts.map +1 -0
  15. package/dist/authz/mcp-oauth.controller.js +305 -0
  16. package/dist/authz/mcp-oauth.controller.js.map +1 -0
  17. package/dist/authz/mcp-oauth.module.d.ts +11 -0
  18. package/dist/authz/mcp-oauth.module.d.ts.map +1 -0
  19. package/dist/authz/mcp-oauth.module.js +173 -0
  20. package/dist/authz/mcp-oauth.module.js.map +1 -0
  21. package/dist/authz/providers/github.provider.d.ts +3 -0
  22. package/dist/authz/providers/github.provider.d.ts.map +1 -0
  23. package/dist/authz/providers/github.provider.js +23 -0
  24. package/dist/authz/providers/github.provider.js.map +1 -0
  25. package/dist/authz/providers/google.provider.d.ts +3 -0
  26. package/dist/authz/providers/google.provider.d.ts.map +1 -0
  27. package/dist/authz/providers/google.provider.js +24 -0
  28. package/dist/authz/providers/google.provider.js.map +1 -0
  29. package/dist/authz/providers/oauth-provider.interface.d.ts +75 -0
  30. package/dist/authz/providers/oauth-provider.interface.d.ts.map +1 -0
  31. package/dist/authz/providers/oauth-provider.interface.js +3 -0
  32. package/dist/authz/providers/oauth-provider.interface.js.map +1 -0
  33. package/dist/authz/services/client.service.d.ts +10 -0
  34. package/dist/authz/services/client.service.d.ts.map +1 -0
  35. package/dist/authz/services/client.service.js +84 -0
  36. package/dist/authz/services/client.service.js.map +1 -0
  37. package/dist/authz/services/jwt-token.service.d.ts +29 -0
  38. package/dist/authz/services/jwt-token.service.d.ts.map +1 -0
  39. package/dist/authz/services/jwt-token.service.js +103 -0
  40. package/dist/authz/services/jwt-token.service.js.map +1 -0
  41. package/dist/authz/services/oauth-strategy.service.d.ts +11 -0
  42. package/dist/authz/services/oauth-strategy.service.d.ts.map +1 -0
  43. package/dist/authz/services/oauth-strategy.service.js +64 -0
  44. package/dist/authz/services/oauth-strategy.service.js.map +1 -0
  45. package/dist/authz/stores/memory-store.service.d.ts +19 -0
  46. package/dist/authz/stores/memory-store.service.d.ts.map +1 -0
  47. package/dist/authz/stores/memory-store.service.js +84 -0
  48. package/dist/authz/stores/memory-store.service.js.map +1 -0
  49. package/dist/authz/stores/memory-store.service.spec.d.ts +2 -0
  50. package/dist/authz/stores/memory-store.service.spec.d.ts.map +1 -0
  51. package/dist/authz/stores/memory-store.service.spec.js +195 -0
  52. package/dist/authz/stores/memory-store.service.spec.js.map +1 -0
  53. package/dist/authz/stores/oauth-store.interface.d.ts +52 -0
  54. package/dist/authz/stores/oauth-store.interface.d.ts.map +1 -0
  55. package/dist/authz/stores/oauth-store.interface.js +3 -0
  56. package/dist/authz/stores/oauth-store.interface.js.map +1 -0
  57. package/dist/authz/stores/sqlite/sqlite-store.service.d.ts +18 -0
  58. package/dist/authz/stores/sqlite/sqlite-store.service.d.ts.map +1 -0
  59. package/dist/authz/stores/sqlite/sqlite-store.service.js +206 -0
  60. package/dist/authz/stores/sqlite/sqlite-store.service.js.map +1 -0
  61. package/dist/authz/stores/typeorm/entities/authorization-code.entity.d.ts +13 -0
  62. package/dist/authz/stores/typeorm/entities/authorization-code.entity.d.ts.map +1 -0
  63. package/dist/authz/stores/typeorm/entities/authorization-code.entity.js +60 -0
  64. package/dist/authz/stores/typeorm/entities/authorization-code.entity.js.map +1 -0
  65. package/dist/authz/stores/typeorm/entities/index.d.ts +4 -0
  66. package/dist/authz/stores/typeorm/entities/index.d.ts.map +1 -0
  67. package/dist/authz/stores/typeorm/entities/index.js +10 -0
  68. package/dist/authz/stores/typeorm/entities/index.js.map +1 -0
  69. package/dist/authz/stores/typeorm/entities/oauth-client.entity.d.ts +16 -0
  70. package/dist/authz/stores/typeorm/entities/oauth-client.entity.d.ts.map +1 -0
  71. package/dist/authz/stores/typeorm/entities/oauth-client.entity.js +72 -0
  72. package/dist/authz/stores/typeorm/entities/oauth-client.entity.js.map +1 -0
  73. package/dist/authz/stores/typeorm/entities/oauth-session.entity.d.ts +13 -0
  74. package/dist/authz/stores/typeorm/entities/oauth-session.entity.d.ts.map +1 -0
  75. package/dist/authz/stores/typeorm/entities/oauth-session.entity.js +60 -0
  76. package/dist/authz/stores/typeorm/entities/oauth-session.entity.js.map +1 -0
  77. package/dist/authz/stores/typeorm/typeorm-store.service.d.ts +21 -0
  78. package/dist/authz/stores/typeorm/typeorm-store.service.d.ts.map +1 -0
  79. package/dist/authz/stores/typeorm/typeorm-store.service.js +87 -0
  80. package/dist/authz/stores/typeorm/typeorm-store.service.js.map +1 -0
  81. package/dist/mcp/services/handlers/mcp-tools.handler.d.ts.map +1 -1
  82. package/dist/mcp/services/handlers/mcp-tools.handler.js.map +1 -1
  83. package/package.json +17 -2
  84. package/src/authz/guards/jwt-auth.guard.ts +45 -0
  85. package/src/authz/index.ts +8 -1
  86. package/src/authz/mcp-oauth.controller.ts +394 -0
  87. package/src/authz/mcp-oauth.module.ts +235 -0
  88. package/src/authz/providers/github.provider.ts +24 -0
  89. package/src/authz/providers/google.provider.ts +22 -0
  90. package/src/authz/providers/oauth-provider.interface.ts +102 -0
  91. package/src/authz/services/client.service.ts +110 -0
  92. package/src/authz/services/jwt-token.service.ts +127 -0
  93. package/src/authz/services/oauth-strategy.service.ts +55 -0
  94. package/src/authz/stores/memory-store.service.spec.ts +240 -0
  95. package/src/authz/stores/memory-store.service.ts +100 -0
  96. package/src/authz/stores/oauth-store.interface.ts +105 -0
  97. package/src/authz/stores/sqlite/sqlite-store.service.ts +279 -0
  98. package/src/authz/stores/typeorm/README.md +133 -0
  99. package/src/authz/stores/typeorm/entities/authorization-code.entity.ts +34 -0
  100. package/src/authz/stores/typeorm/entities/index.ts +3 -0
  101. package/src/authz/stores/typeorm/entities/oauth-client.entity.ts +49 -0
  102. package/src/authz/stores/typeorm/entities/oauth-session.entity.ts +34 -0
  103. package/src/authz/stores/typeorm/typeorm-store.service.ts +98 -0
  104. package/src/mcp/services/handlers/mcp-tools.handler.ts +5 -2
@@ -0,0 +1,13 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import { Request } from 'express';
3
+ import { JwtPayload, JwtTokenService } from '../services/jwt-token.service';
4
+ export interface AuthenticatedRequest extends Request {
5
+ user: JwtPayload;
6
+ }
7
+ export declare class JwtAuthGuard implements CanActivate {
8
+ private readonly jwtTokenService;
9
+ constructor(jwtTokenService: JwtTokenService);
10
+ canActivate(context: ExecutionContext): boolean;
11
+ private extractTokenFromHeader;
12
+ }
13
+ //# sourceMappingURL=jwt-auth.guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt-auth.guard.d.ts","sourceRoot":"","sources":["../../../src/authz/guards/jwt-auth.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAE5E,MAAM,WAAW,oBAAqB,SAAQ,OAAO;IACnD,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,qBACa,YAAa,YAAW,WAAW;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAAf,eAAe,EAAE,eAAe;IAE7D,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;IAkB/C,OAAO,CAAC,sBAAsB;CAS/B"}
@@ -0,0 +1,46 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.JwtAuthGuard = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const jwt_token_service_1 = require("../services/jwt-token.service");
15
+ let JwtAuthGuard = class JwtAuthGuard {
16
+ constructor(jwtTokenService) {
17
+ this.jwtTokenService = jwtTokenService;
18
+ }
19
+ canActivate(context) {
20
+ const request = context.switchToHttp().getRequest();
21
+ const token = this.extractTokenFromHeader(request);
22
+ if (!token) {
23
+ throw new common_1.UnauthorizedException('Access token required');
24
+ }
25
+ const payload = this.jwtTokenService.validateToken(token);
26
+ if (!payload || payload.type !== 'access') {
27
+ throw new common_1.UnauthorizedException('Invalid or expired access token');
28
+ }
29
+ request.user = payload;
30
+ return true;
31
+ }
32
+ extractTokenFromHeader(request) {
33
+ const authHeader = request.headers.authorization;
34
+ if (!authHeader) {
35
+ return undefined;
36
+ }
37
+ const [type, token] = authHeader.split(' ');
38
+ return type === 'Bearer' ? token : undefined;
39
+ }
40
+ };
41
+ exports.JwtAuthGuard = JwtAuthGuard;
42
+ exports.JwtAuthGuard = JwtAuthGuard = __decorate([
43
+ (0, common_1.Injectable)(),
44
+ __metadata("design:paramtypes", [jwt_token_service_1.JwtTokenService])
45
+ ], JwtAuthGuard);
46
+ //# sourceMappingURL=jwt-auth.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt-auth.guard.js","sourceRoot":"","sources":["../../../src/authz/guards/jwt-auth.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAKwB;AAExB,qEAA4E;AAOrE,IAAM,YAAY,GAAlB,MAAM,YAAY;IACvB,YAA6B,eAAgC;QAAhC,oBAAe,GAAf,eAAe,CAAiB;IAAG,CAAC;IAEjE,WAAW,CAAC,OAAyB;QACnC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAwB,CAAC;QAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,8BAAqB,CAAC,uBAAuB,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE1D,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1C,MAAM,IAAI,8BAAqB,CAAC,iCAAiC,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,sBAAsB,CAAC,OAAgB;QAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QACjD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5C,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/C,CAAC;CACF,CAAA;AA9BY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;qCAEmC,mCAAe;GADlD,YAAY,CA8BxB","sourcesContent":["import {\n Injectable,\n CanActivate,\n ExecutionContext,\n UnauthorizedException,\n} from '@nestjs/common';\nimport { Request } from 'express';\nimport { JwtPayload, JwtTokenService } from '../services/jwt-token.service';\n\nexport interface AuthenticatedRequest extends Request {\n user: JwtPayload;\n}\n\n@Injectable()\nexport class JwtAuthGuard implements CanActivate {\n constructor(private readonly jwtTokenService: JwtTokenService) {}\n\n canActivate(context: ExecutionContext): boolean {\n const request = context.switchToHttp().getRequest<AuthenticatedRequest>();\n const token = this.extractTokenFromHeader(request);\n\n if (!token) {\n throw new UnauthorizedException('Access token required');\n }\n\n const payload = this.jwtTokenService.validateToken(token);\n\n if (!payload || payload.type !== 'access') {\n throw new UnauthorizedException('Invalid or expired access token');\n }\n\n request.user = payload;\n return true;\n }\n\n private extractTokenFromHeader(request: Request): string | undefined {\n const authHeader = request.headers.authorization;\n if (!authHeader) {\n return undefined;\n }\n\n const [type, token] = authHeader.split(' ');\n return type === 'Bearer' ? token : undefined;\n }\n}\n"]}
@@ -1,2 +1,9 @@
1
- export {};
1
+ export * from './mcp-oauth.controller';
2
+ export * from './mcp-oauth.module';
3
+ export * from './providers/oauth-provider.interface';
4
+ export * from './providers/google.provider';
5
+ export * from './providers/github.provider';
6
+ export * from './stores/oauth-store.interface';
7
+ export * from './stores/memory-store.service';
8
+ export * from './stores/typeorm/typeorm-store.service';
2
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/authz/index.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/authz/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sCAAsC,CAAC;AACrD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC"}
@@ -1,3 +1,25 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./mcp-oauth.controller"), exports);
18
+ __exportStar(require("./mcp-oauth.module"), exports);
19
+ __exportStar(require("./providers/oauth-provider.interface"), exports);
20
+ __exportStar(require("./providers/google.provider"), exports);
21
+ __exportStar(require("./providers/github.provider"), exports);
22
+ __exportStar(require("./stores/oauth-store.interface"), exports);
23
+ __exportStar(require("./stores/memory-store.service"), exports);
24
+ __exportStar(require("./stores/typeorm/typeorm-store.service"), exports);
3
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/authz/index.ts"],"names":[],"mappings":"","sourcesContent":["\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/authz/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yDAAuC;AACvC,qDAAmC;AACnC,uEAAqD;AACrD,8DAA4C;AAC5C,8DAA4C;AAC5C,iEAA+C;AAC/C,gEAA8C;AAC9C,yEAAuD","sourcesContent":["export * from './mcp-oauth.controller';\nexport * from './mcp-oauth.module';\nexport * from './providers/oauth-provider.interface';\nexport * from './providers/google.provider';\nexport * from './providers/github.provider';\nexport * from './stores/oauth-store.interface';\nexport * from './stores/memory-store.service';\nexport * from './stores/typeorm/typeorm-store.service';\n"]}
@@ -0,0 +1,3 @@
1
+ export * from '../providers/oauth-provider.interface';
2
+ export * from '../stores/oauth-store.interface';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/authz/interfaces/index.ts"],"names":[],"mappings":"AACA,cAAc,uCAAuC,CAAC;AACtD,cAAc,iCAAiC,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("../providers/oauth-provider.interface"), exports);
18
+ __exportStar(require("../stores/oauth-store.interface"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authz/interfaces/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,wEAAsD;AACtD,kEAAgD","sourcesContent":["// Re-export main interfaces\nexport * from '../providers/oauth-provider.interface';\nexport * from '../stores/oauth-store.interface';\n\n/**\n * @fileoverview Store Configuration Examples\n *\n * The `storeConfiguration` property in `OAuthUserModuleOptions` allows you to configure\n * how OAuth sessions, authorization codes, and client information are stored.\n *\n * @example\n * // Option 1: Memory Store (default)\n * // Just omit storeConfiguration or explicitly set it\n * storeConfiguration: { type: 'memory' }\n *\n * @example\n * // Option 2: Custom Store Implementation\n * import { MyCustomStore } from './my-custom-store';\n * storeConfiguration: {\n * type: 'custom',\n * store: new MyCustomStore()\n * }\n *\n * @example\n * // Option 3: TypeORM Persistent Storage\n * storeConfiguration: {\n * type: 'typeorm',\n * options: {\n * type: 'sqlite',\n * database: './oauth.db',\n * synchronize: true,\n * logging: false\n * }\n * }\n *\n * @example\n * // Option 3b: TypeORM with PostgreSQL\n * storeConfiguration: {\n * type: 'typeorm',\n * options: {\n * type: 'postgres',\n * host: process.env.DB_HOST || 'localhost',\n * port: parseInt(process.env.DB_PORT) || 5432,\n * username: process.env.DB_USERNAME || 'postgres',\n * password: process.env.DB_PASSWORD || 'password',\n * database: process.env.DB_NAME || 'oauth_db',\n * synchronize: process.env.NODE_ENV !== 'production',\n * logging: process.env.NODE_ENV === 'development'\n * }\n * }\n */\n"]}
@@ -0,0 +1,53 @@
1
+ import { Request as ExpressRequest, NextFunction, Response } 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, TokenPair } from './services/jwt-token.service';
6
+ import { ClientRegistrationDto, IOAuthStore } from './stores/oauth-store.interface';
7
+ interface OAuthCallbackRequest extends ExpressRequest {
8
+ user?: {
9
+ profile: OAuthUserProfile;
10
+ accessToken: string;
11
+ provider: string;
12
+ };
13
+ }
14
+ export declare class McpOAuthController {
15
+ private options;
16
+ private readonly store;
17
+ private readonly jwtTokenService;
18
+ private readonly clientService;
19
+ private readonly serverUrl;
20
+ private readonly isProduction;
21
+ constructor(options: OAuthModuleOptions, store: IOAuthStore, jwtTokenService: JwtTokenService, clientService: ClientService);
22
+ getAuthorizationServerMetadata(): {
23
+ issuer: string;
24
+ authorization_endpoint: string;
25
+ token_endpoint: string;
26
+ registration_endpoint: string;
27
+ response_types_supported: string[];
28
+ response_modes_supported: string[];
29
+ grant_types_supported: string[];
30
+ token_endpoint_auth_methods_supported: string[];
31
+ revocation_endpoint: string;
32
+ code_challenge_methods_supported: string[];
33
+ };
34
+ registerClient(registrationDto: ClientRegistrationDto): Promise<import("./stores/oauth-store.interface").OAuthClient>;
35
+ authorize(query: any, res: Response): Promise<void>;
36
+ authenticate(req: any, res: Response, next: NextFunction): void;
37
+ handleProviderCallback(req: OAuthCallbackRequest, res: Response, next: NextFunction): Promise<void>;
38
+ private processAuthenticationSuccess;
39
+ exchangeToken(body: any): Promise<TokenPair>;
40
+ private handleAuthorizationCodeGrant;
41
+ private handleRefreshTokenGrant;
42
+ validateToken(req: AuthenticatedRequest): {
43
+ valid: boolean;
44
+ user_id: string;
45
+ client_id: string | undefined;
46
+ scope: string | undefined;
47
+ expires_at: number;
48
+ };
49
+ private parseExpiresInToMs;
50
+ private validatePKCE;
51
+ }
52
+ export {};
53
+ //# sourceMappingURL=mcp-oauth.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-oauth.controller.d.ts","sourceRoot":"","sources":["../../src/authz/mcp-oauth.controller.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE5E,OAAO,EAAE,oBAAoB,EAAgB,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EACL,kBAAkB,EAElB,gBAAgB,EACjB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE1E,OAAO,EACL,qBAAqB,EACrB,WAAW,EACZ,MAAM,gCAAgC,CAAC;AAExC,UAAU,oBAAqB,SAAQ,cAAc;IACnD,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,gBAAgB,CAAC;QAC1B,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,qBACa,kBAAkB;IAKK,OAAO,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAC7C,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAPhC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;gBAGG,OAAO,EAAE,kBAAkB,EAC3B,KAAK,EAAE,WAAW,EACzC,eAAe,EAAE,eAAe,EAChC,aAAa,EAAE,aAAa;IAQ/C,8BAA8B;;;;;;;;;;;;IAoBxB,cAAc,CAAS,eAAe,EAAE,qBAAqB;IAK7D,SAAS,CAAU,KAAK,EAAE,GAAG,EAAS,GAAG,EAAE,QAAQ;IAuEzD,YAAY,CACH,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,QAAQ,EACZ,IAAI,EAAE,YAAY;IAQtB,sBAAsB,CACnB,GAAG,EAAE,oBAAoB,EACzB,GAAG,EAAE,QAAQ,EACZ,IAAI,EAAE,YAAY;YA0Bd,4BAA4B;IAwEpC,aAAa,CAAS,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC;YAwB5C,4BAA4B;YAgD5B,uBAAuB;IAarC,aAAa,CAAQ,GAAG,EAAE,oBAAoB;;;;;;;IAU9C,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,YAAY;CAerB"}
@@ -0,0 +1,305 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.McpOAuthController = void 0;
19
+ const common_1 = require("@nestjs/common");
20
+ const crypto_1 = require("crypto");
21
+ const passport_1 = __importDefault(require("passport"));
22
+ const jwt_auth_guard_1 = require("./guards/jwt-auth.guard");
23
+ const client_service_1 = require("./services/client.service");
24
+ const jwt_token_service_1 = require("./services/jwt-token.service");
25
+ const oauth_strategy_service_1 = require("./services/oauth-strategy.service");
26
+ let McpOAuthController = class McpOAuthController {
27
+ constructor(options, store, jwtTokenService, clientService) {
28
+ this.options = options;
29
+ this.store = store;
30
+ this.jwtTokenService = jwtTokenService;
31
+ this.clientService = clientService;
32
+ this.serverUrl = this.options.serverUrl;
33
+ this.isProduction = this.options.cookieSecure;
34
+ }
35
+ getAuthorizationServerMetadata() {
36
+ return {
37
+ issuer: this.serverUrl,
38
+ authorization_endpoint: `${this.serverUrl}/authorize`,
39
+ token_endpoint: `${this.serverUrl}/token`,
40
+ registration_endpoint: `${this.serverUrl}/register`,
41
+ response_types_supported: ['code'],
42
+ response_modes_supported: ['query'],
43
+ grant_types_supported: ['authorization_code', 'refresh_token'],
44
+ token_endpoint_auth_methods_supported: [
45
+ 'client_secret_basic',
46
+ 'client_secret_post',
47
+ 'none',
48
+ ],
49
+ revocation_endpoint: `${this.serverUrl}/revoke`,
50
+ code_challenge_methods_supported: ['plain', 'S256'],
51
+ };
52
+ }
53
+ async registerClient(registrationDto) {
54
+ return await this.clientService.registerClient(registrationDto);
55
+ }
56
+ async authorize(query, res) {
57
+ const { response_type, client_id, redirect_uri, code_challenge, code_challenge_method, state, resource, } = query;
58
+ if (response_type !== 'code') {
59
+ throw new common_1.BadRequestException('Only response_type=code is supported');
60
+ }
61
+ if (!client_id || !redirect_uri || !code_challenge) {
62
+ throw new common_1.BadRequestException('Missing required parameters');
63
+ }
64
+ const client = await this.clientService.getClient(client_id);
65
+ if (!client) {
66
+ throw new common_1.BadRequestException('Invalid client_id');
67
+ }
68
+ const validRedirect = await this.clientService.validateRedirectUri(client_id, redirect_uri);
69
+ if (!validRedirect) {
70
+ throw new common_1.BadRequestException('Invalid redirect_uri');
71
+ }
72
+ const sessionId = (0, crypto_1.randomBytes)(32).toString('base64url');
73
+ const sessionState = (0, crypto_1.randomBytes)(32).toString('base64url');
74
+ const oauthSession = {
75
+ sessionId,
76
+ state: sessionState,
77
+ clientId: client_id,
78
+ redirectUri: redirect_uri,
79
+ codeChallenge: code_challenge,
80
+ codeChallengeMethod: code_challenge_method || 'plain',
81
+ oauthState: state,
82
+ resource,
83
+ expiresAt: Date.now() + this.options.oauthSessionExpiresIn,
84
+ };
85
+ this.store.storeOAuthSession(sessionId, oauthSession);
86
+ res.cookie('oauth_session', sessionId, {
87
+ httpOnly: true,
88
+ secure: this.isProduction,
89
+ maxAge: this.options.oauthSessionExpiresIn,
90
+ });
91
+ res.cookie('oauth_state', sessionState, {
92
+ httpOnly: true,
93
+ secure: this.isProduction,
94
+ maxAge: this.options.oauthSessionExpiresIn,
95
+ });
96
+ res.redirect(`/auth`);
97
+ }
98
+ authenticate(req, res, next) {
99
+ passport_1.default.authenticate(oauth_strategy_service_1.STRATEGY_NAME, {
100
+ state: req.cookies?.oauth_state,
101
+ })(req, res, next);
102
+ }
103
+ async handleProviderCallback(req, res, next) {
104
+ passport_1.default.authenticate(oauth_strategy_service_1.STRATEGY_NAME, { session: false }, async (err, user) => {
105
+ try {
106
+ if (err) {
107
+ console.error('OAuth callback error:', err);
108
+ throw new common_1.BadRequestException('Authentication failed');
109
+ }
110
+ if (!user) {
111
+ throw new common_1.BadRequestException('Authentication failed');
112
+ }
113
+ req.user = user;
114
+ await this.processAuthenticationSuccess(req, res);
115
+ }
116
+ catch (error) {
117
+ next(error);
118
+ }
119
+ })(req, res, next);
120
+ }
121
+ async processAuthenticationSuccess(req, res) {
122
+ const user = req.user;
123
+ if (!user) {
124
+ throw new common_1.BadRequestException('Authentication failed');
125
+ }
126
+ const sessionId = req.cookies?.oauth_session;
127
+ if (!sessionId) {
128
+ throw new common_1.BadRequestException('Missing OAuth session');
129
+ }
130
+ const session = await this.store.getOAuthSession(sessionId);
131
+ if (!session || session.expiresAt < Date.now()) {
132
+ throw new common_1.BadRequestException('Invalid or expired OAuth session');
133
+ }
134
+ const stateFromCookie = req.cookies?.oauth_state;
135
+ if (session.state !== stateFromCookie) {
136
+ throw new common_1.BadRequestException('Invalid state parameter');
137
+ }
138
+ const jwt = this.jwtTokenService.generateUserToken(user.profile.username, user.profile);
139
+ res.cookie('auth_token', jwt, {
140
+ httpOnly: true,
141
+ secure: this.isProduction,
142
+ maxAge: this.options.cookieMaxAge,
143
+ });
144
+ res.clearCookie('oauth_session');
145
+ res.clearCookie('oauth_state');
146
+ const authCode = (0, crypto_1.randomBytes)(32).toString('base64url');
147
+ this.store.storeAuthCode({
148
+ code: authCode,
149
+ user_id: user.profile.username,
150
+ client_id: session.clientId,
151
+ redirect_uri: session.redirectUri,
152
+ code_challenge: session.codeChallenge,
153
+ code_challenge_method: session.codeChallengeMethod,
154
+ expires_at: Date.now() + this.options.authCodeExpiresIn,
155
+ github_access_token: '',
156
+ });
157
+ const redirectUrl = new URL(session.redirectUri);
158
+ redirectUrl.searchParams.set('code', authCode);
159
+ if (session.oauthState) {
160
+ redirectUrl.searchParams.set('state', session.oauthState);
161
+ }
162
+ this.store.removeOAuthSession(sessionId);
163
+ res.redirect(redirectUrl.toString());
164
+ }
165
+ async exchangeToken(body) {
166
+ const { grant_type, code, code_verifier, redirect_uri, client_id, refresh_token, } = body;
167
+ if (grant_type === 'authorization_code') {
168
+ return this.handleAuthorizationCodeGrant(code, code_verifier, redirect_uri, client_id);
169
+ }
170
+ else if (grant_type === 'refresh_token') {
171
+ return this.handleRefreshTokenGrant(refresh_token);
172
+ }
173
+ else {
174
+ throw new common_1.BadRequestException('Unsupported grant_type');
175
+ }
176
+ }
177
+ async handleAuthorizationCodeGrant(code, code_verifier, redirect_uri, client_id) {
178
+ const authCode = await this.store.getAuthCode(code);
179
+ if (!authCode) {
180
+ throw new common_1.BadRequestException('Invalid authorization code');
181
+ }
182
+ if (authCode.expires_at < Date.now()) {
183
+ await this.store.removeAuthCode(code);
184
+ throw new common_1.BadRequestException('Authorization code has expired');
185
+ }
186
+ if (authCode.client_id !== client_id) {
187
+ throw new common_1.BadRequestException('Client ID mismatch');
188
+ }
189
+ if (authCode.code_challenge) {
190
+ const isValid = this.validatePKCE(code_verifier, authCode.code_challenge, authCode.code_challenge_method);
191
+ if (!isValid) {
192
+ throw new common_1.BadRequestException('Invalid PKCE verification');
193
+ }
194
+ }
195
+ const tokens = this.jwtTokenService.generateTokenPair(authCode.user_id, client_id, 'mcp:access');
196
+ this.store.removeAuthCode(code);
197
+ return tokens;
198
+ }
199
+ async handleRefreshTokenGrant(refresh_token) {
200
+ const newTokens = this.jwtTokenService.refreshAccessToken(refresh_token);
201
+ if (!newTokens) {
202
+ throw new common_1.BadRequestException('Failed to refresh token');
203
+ }
204
+ return newTokens;
205
+ }
206
+ validateToken(req) {
207
+ return {
208
+ valid: true,
209
+ user_id: req.user.sub,
210
+ client_id: req.user.client_id,
211
+ scope: req.user.scope,
212
+ expires_at: req.user.exp * 1000,
213
+ };
214
+ }
215
+ parseExpiresInToMs(expiresIn) {
216
+ const match = expiresIn.match(/^(\d+)([smhd]?)$/);
217
+ if (!match) {
218
+ throw new Error(`Invalid expiresIn format: ${expiresIn}`);
219
+ }
220
+ const value = parseInt(match[1], 10);
221
+ const unit = match[2] || 's';
222
+ const multipliers = {
223
+ s: 1000,
224
+ m: 60 * 1000,
225
+ h: 60 * 60 * 1000,
226
+ d: 24 * 60 * 60 * 1000,
227
+ };
228
+ return value * multipliers[unit];
229
+ }
230
+ validatePKCE(code_verifier, code_challenge, method) {
231
+ if (method === 'plain') {
232
+ return code_verifier === code_challenge;
233
+ }
234
+ else if (method === 'S256') {
235
+ const hash = (0, crypto_1.createHash)('sha256')
236
+ .update(code_verifier)
237
+ .digest('base64url');
238
+ return hash === code_challenge;
239
+ }
240
+ return false;
241
+ }
242
+ };
243
+ exports.McpOAuthController = McpOAuthController;
244
+ __decorate([
245
+ (0, common_1.Get)('/.well-known/oauth-authorization-server'),
246
+ __metadata("design:type", Function),
247
+ __metadata("design:paramtypes", []),
248
+ __metadata("design:returntype", void 0)
249
+ ], McpOAuthController.prototype, "getAuthorizationServerMetadata", null);
250
+ __decorate([
251
+ (0, common_1.Post)('/register'),
252
+ __param(0, (0, common_1.Body)()),
253
+ __metadata("design:type", Function),
254
+ __metadata("design:paramtypes", [Object]),
255
+ __metadata("design:returntype", Promise)
256
+ ], McpOAuthController.prototype, "registerClient", null);
257
+ __decorate([
258
+ (0, common_1.Get)('/authorize'),
259
+ __param(0, (0, common_1.Query)()),
260
+ __param(1, (0, common_1.Res)()),
261
+ __metadata("design:type", Function),
262
+ __metadata("design:paramtypes", [Object, Object]),
263
+ __metadata("design:returntype", Promise)
264
+ ], McpOAuthController.prototype, "authorize", null);
265
+ __decorate([
266
+ (0, common_1.Get)('/auth'),
267
+ __param(0, (0, common_1.Req)()),
268
+ __param(1, (0, common_1.Res)()),
269
+ __param(2, (0, common_1.Next)()),
270
+ __metadata("design:type", Function),
271
+ __metadata("design:paramtypes", [Object, Object, Function]),
272
+ __metadata("design:returntype", void 0)
273
+ ], McpOAuthController.prototype, "authenticate", null);
274
+ __decorate([
275
+ (0, common_1.Get)('/auth/callback'),
276
+ __param(0, (0, common_1.Req)()),
277
+ __param(1, (0, common_1.Res)()),
278
+ __param(2, (0, common_1.Next)()),
279
+ __metadata("design:type", Function),
280
+ __metadata("design:paramtypes", [Object, Object, Function]),
281
+ __metadata("design:returntype", Promise)
282
+ ], McpOAuthController.prototype, "handleProviderCallback", null);
283
+ __decorate([
284
+ (0, common_1.Post)('/token'),
285
+ __param(0, (0, common_1.Body)()),
286
+ __metadata("design:type", Function),
287
+ __metadata("design:paramtypes", [Object]),
288
+ __metadata("design:returntype", Promise)
289
+ ], McpOAuthController.prototype, "exchangeToken", null);
290
+ __decorate([
291
+ (0, common_1.Get)('/validate'),
292
+ (0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
293
+ __param(0, (0, common_1.Req)()),
294
+ __metadata("design:type", Function),
295
+ __metadata("design:paramtypes", [Object]),
296
+ __metadata("design:returntype", void 0)
297
+ ], McpOAuthController.prototype, "validateToken", null);
298
+ exports.McpOAuthController = McpOAuthController = __decorate([
299
+ (0, common_1.Controller)(),
300
+ __param(0, (0, common_1.Inject)('OAUTH_MODULE_OPTIONS')),
301
+ __param(1, (0, common_1.Inject)('IOAuthStore')),
302
+ __metadata("design:paramtypes", [Object, Object, jwt_token_service_1.JwtTokenService,
303
+ client_service_1.ClientService])
304
+ ], McpOAuthController);
305
+ //# sourceMappingURL=mcp-oauth.controller.js.map
@@ -0,0 +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 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, JwtAuthGuard } from './guards/jwt-auth.guard';\nimport {\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';\n\ninterface OAuthCallbackRequest extends ExpressRequest {\n user?: {\n profile: OAuthUserProfile;\n accessToken: string;\n provider: string;\n };\n}\n\n@Controller()\nexport class McpOAuthController {\n private readonly serverUrl: string;\n private readonly isProduction: boolean;\n\n constructor(\n @Inject('OAUTH_MODULE_OPTIONS') private options: OAuthModuleOptions,\n @Inject('IOAuthStore') private readonly store: IOAuthStore,\n private readonly jwtTokenService: JwtTokenService,\n private readonly clientService: ClientService,\n ) {\n this.serverUrl = this.options.serverUrl;\n this.isProduction = this.options.cookieSecure;\n }\n\n // OAuth endpoints\n @Get('/.well-known/oauth-authorization-server')\n getAuthorizationServerMetadata() {\n return {\n issuer: this.serverUrl,\n authorization_endpoint: `${this.serverUrl}/authorize`,\n token_endpoint: `${this.serverUrl}/token`,\n registration_endpoint: `${this.serverUrl}/register`,\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: `${this.serverUrl}/revoke`,\n code_challenge_methods_supported: ['plain', 'S256'],\n };\n }\n\n @Post('/register')\n async registerClient(@Body() registrationDto: ClientRegistrationDto) {\n return await this.clientService.registerClient(registrationDto);\n }\n\n @Get('/authorize')\n async authorize(@Query() query: any, @Res() res: Response) {\n const {\n response_type,\n client_id,\n redirect_uri,\n code_challenge,\n code_challenge_method,\n state,\n resource,\n } = query;\n\n // Validate parameters\n if (response_type !== 'code') {\n throw new BadRequestException('Only response_type=code is supported');\n }\n\n if (!client_id || !redirect_uri || !code_challenge) {\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 resource,\n expiresAt: Date.now() + this.options.oauthSessionExpiresIn,\n };\n\n 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 res.redirect(`/auth`);\n }\n\n @Get('/auth')\n authenticate(\n @Req() req: any,\n @Res() res: Response,\n @Next() next: NextFunction,\n ) {\n passport.authenticate(STRATEGY_NAME, {\n state: req.cookies?.oauth_state,\n })(req, res, next);\n }\n\n @Get('/auth/callback')\n async 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 console.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 private 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 || session.expiresAt < Date.now()) {\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 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 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 this.store.removeOAuthSession(sessionId);\n\n res.redirect(redirectUrl.toString());\n }\n\n // Token endpoints (remain the same)\n @Post('/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 private async handleAuthorizationCodeGrant(\n code: string,\n code_verifier: string,\n redirect_uri: string,\n client_id: string,\n ): Promise<TokenPair> {\n // Validate the authorization code\n const authCode = await this.store.getAuthCode(code);\n if (!authCode) {\n throw new BadRequestException('Invalid authorization code');\n }\n\n // Check if code has expired\n if (authCode.expires_at < Date.now()) {\n await this.store.removeAuthCode(code);\n throw new BadRequestException('Authorization code has expired');\n }\n\n // Validate client_id matches\n if (authCode.client_id !== client_id) {\n throw new BadRequestException('Client ID mismatch');\n }\n\n // Validate PKCE if required\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 throw new BadRequestException('Invalid PKCE verification');\n }\n }\n\n // Generate tokens\n const tokens = this.jwtTokenService.generateTokenPair(\n authCode.user_id,\n client_id,\n 'mcp:access',\n );\n\n // Remove the used authorization code\n this.store.removeAuthCode(code);\n\n return tokens;\n }\n\n private async handleRefreshTokenGrant(\n refresh_token: string,\n ): Promise<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('/validate')\n @UseGuards(JwtAuthGuard)\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 private parseExpiresInToMs(expiresIn: string): number {\n // Handle formats like \"60s\", \"30d\", \"24h\", \"1440m\"\n const match = expiresIn.match(/^(\\d+)([smhd]?)$/);\n if (!match) {\n throw new Error(`Invalid expiresIn format: ${expiresIn}`);\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2] || 's'; // default to seconds\n\n const multipliers = {\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n };\n\n return value * multipliers[unit as keyof typeof multipliers];\n }\n\n private 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"]}
@@ -0,0 +1,11 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { OAuthModuleDefaults, OAuthUserModuleOptions as AuthUserModuleOptions } from './providers/oauth-provider.interface';
3
+ export declare const DEFAULT_OPTIONS: OAuthModuleDefaults;
4
+ export declare class McpAuthModule {
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=mcp-oauth.module.d.ts.map
@@ -0,0 +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;AAU/D,OAAO,EACL,mBAAmB,EAEnB,sBAAsB,IAAI,qBAAqB,EAChD,MAAM,sCAAsC,CAAC;AAU9C,eAAO,MAAM,eAAe,EAAE,mBAU7B,CAAC;AAEF,qBAEa,aAAa;IACxB,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,qBAAqB,GAAG,aAAa;IA4F7D,OAAO,CAAC,MAAM,CAAC,uBAAuB;IA2BtC,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAmBtC,OAAO,CAAC,MAAM,CAAC,uBAAuB;IA0BtC,OAAO,CAAC,MAAM,CAAC,mBAAmB;CA+BnC"}