couchloop-eq-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +358 -0
  3. package/assets/logo/README.md +12 -0
  4. package/assets/logo/couchloop_EQ-IconLogo.png +0 -0
  5. package/dist/auth/middleware.d.ts +8 -0
  6. package/dist/auth/middleware.d.ts.map +1 -0
  7. package/dist/auth/middleware.js +59 -0
  8. package/dist/auth/middleware.js.map +1 -0
  9. package/dist/clients/shrinkChatClient.d.ts +195 -0
  10. package/dist/clients/shrinkChatClient.d.ts.map +1 -0
  11. package/dist/clients/shrinkChatClient.js +349 -0
  12. package/dist/clients/shrinkChatClient.js.map +1 -0
  13. package/dist/db/client.d.ts +23 -0
  14. package/dist/db/client.d.ts.map +1 -0
  15. package/dist/db/client.js +78 -0
  16. package/dist/db/client.js.map +1 -0
  17. package/dist/db/migrate.d.ts +4 -0
  18. package/dist/db/migrate.d.ts.map +1 -0
  19. package/dist/db/migrate.js +34 -0
  20. package/dist/db/migrate.js.map +1 -0
  21. package/dist/db/migrations/schema.d.ts +1074 -0
  22. package/dist/db/migrations/schema.d.ts.map +1 -0
  23. package/dist/db/migrations/schema.js +160 -0
  24. package/dist/db/migrations/schema.js.map +1 -0
  25. package/dist/db/schema.d.ts +1213 -0
  26. package/dist/db/schema.d.ts.map +1 -0
  27. package/dist/db/schema.js +157 -0
  28. package/dist/db/schema.js.map +1 -0
  29. package/dist/db/seed.d.ts +4 -0
  30. package/dist/db/seed.d.ts.map +1 -0
  31. package/dist/db/seed.js +57 -0
  32. package/dist/db/seed.js.map +1 -0
  33. package/dist/db/seedOAuth.d.ts +4 -0
  34. package/dist/db/seedOAuth.d.ts.map +1 -0
  35. package/dist/db/seedOAuth.js +76 -0
  36. package/dist/db/seedOAuth.js.map +1 -0
  37. package/dist/index.d.ts +3 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +93 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/resources/index.d.ts +11 -0
  42. package/dist/resources/index.d.ts.map +1 -0
  43. package/dist/resources/index.js +56 -0
  44. package/dist/resources/index.js.map +1 -0
  45. package/dist/resources/journey-status.d.ts +2 -0
  46. package/dist/resources/journey-status.d.ts.map +1 -0
  47. package/dist/resources/journey-status.js +42 -0
  48. package/dist/resources/journey-status.js.map +1 -0
  49. package/dist/resources/session-summary.d.ts +2 -0
  50. package/dist/resources/session-summary.d.ts.map +1 -0
  51. package/dist/resources/session-summary.js +85 -0
  52. package/dist/resources/session-summary.js.map +1 -0
  53. package/dist/resources/user-context.d.ts +2 -0
  54. package/dist/resources/user-context.d.ts.map +1 -0
  55. package/dist/resources/user-context.js +79 -0
  56. package/dist/resources/user-context.js.map +1 -0
  57. package/dist/server/index.d.ts +3 -0
  58. package/dist/server/index.d.ts.map +1 -0
  59. package/dist/server/index.js +385 -0
  60. package/dist/server/index.js.map +1 -0
  61. package/dist/server/middleware/auth.d.ts +30 -0
  62. package/dist/server/middleware/auth.d.ts.map +1 -0
  63. package/dist/server/middleware/auth.js +157 -0
  64. package/dist/server/middleware/auth.js.map +1 -0
  65. package/dist/server/oauth/anomalyDetection.d.ts +146 -0
  66. package/dist/server/oauth/anomalyDetection.d.ts.map +1 -0
  67. package/dist/server/oauth/anomalyDetection.js +405 -0
  68. package/dist/server/oauth/anomalyDetection.js.map +1 -0
  69. package/dist/server/oauth/authServer.d.ts +61 -0
  70. package/dist/server/oauth/authServer.d.ts.map +1 -0
  71. package/dist/server/oauth/authServer.js +283 -0
  72. package/dist/server/oauth/authServer.js.map +1 -0
  73. package/dist/server/oauth/dpop.d.ts +135 -0
  74. package/dist/server/oauth/dpop.d.ts.map +1 -0
  75. package/dist/server/oauth/dpop.js +338 -0
  76. package/dist/server/oauth/dpop.js.map +1 -0
  77. package/dist/server/oauth/gdpr/consent.d.ts +173 -0
  78. package/dist/server/oauth/gdpr/consent.d.ts.map +1 -0
  79. package/dist/server/oauth/gdpr/consent.js +388 -0
  80. package/dist/server/oauth/gdpr/consent.js.map +1 -0
  81. package/dist/server/oauth/gdpr/dataPortability.d.ts +214 -0
  82. package/dist/server/oauth/gdpr/dataPortability.d.ts.map +1 -0
  83. package/dist/server/oauth/gdpr/dataPortability.js +486 -0
  84. package/dist/server/oauth/gdpr/dataPortability.js.map +1 -0
  85. package/dist/server/oauth/gdpr/index.d.ts +103 -0
  86. package/dist/server/oauth/gdpr/index.d.ts.map +1 -0
  87. package/dist/server/oauth/gdpr/index.js +273 -0
  88. package/dist/server/oauth/gdpr/index.js.map +1 -0
  89. package/dist/server/oauth/gdpr/rightToErasure.d.ts +184 -0
  90. package/dist/server/oauth/gdpr/rightToErasure.d.ts.map +1 -0
  91. package/dist/server/oauth/gdpr/rightToErasure.js +527 -0
  92. package/dist/server/oauth/gdpr/rightToErasure.js.map +1 -0
  93. package/dist/server/oauth/monitoring/securityMonitor.d.ts +218 -0
  94. package/dist/server/oauth/monitoring/securityMonitor.d.ts.map +1 -0
  95. package/dist/server/oauth/monitoring/securityMonitor.js +615 -0
  96. package/dist/server/oauth/monitoring/securityMonitor.js.map +1 -0
  97. package/dist/server/oauth/pkce.d.ts +61 -0
  98. package/dist/server/oauth/pkce.d.ts.map +1 -0
  99. package/dist/server/oauth/pkce.js +157 -0
  100. package/dist/server/oauth/pkce.js.map +1 -0
  101. package/dist/server/oauth/providers/base.d.ts +147 -0
  102. package/dist/server/oauth/providers/base.d.ts.map +1 -0
  103. package/dist/server/oauth/providers/base.js +312 -0
  104. package/dist/server/oauth/providers/base.js.map +1 -0
  105. package/dist/server/oauth/providers/github.d.ts +55 -0
  106. package/dist/server/oauth/providers/github.d.ts.map +1 -0
  107. package/dist/server/oauth/providers/github.js +225 -0
  108. package/dist/server/oauth/providers/github.js.map +1 -0
  109. package/dist/server/oauth/providers/google.d.ts +49 -0
  110. package/dist/server/oauth/providers/google.d.ts.map +1 -0
  111. package/dist/server/oauth/providers/google.js +153 -0
  112. package/dist/server/oauth/providers/google.js.map +1 -0
  113. package/dist/server/oauth/providers/index.d.ts +9 -0
  114. package/dist/server/oauth/providers/index.d.ts.map +1 -0
  115. package/dist/server/oauth/providers/index.js +24 -0
  116. package/dist/server/oauth/providers/index.js.map +1 -0
  117. package/dist/server/oauth/refreshTokenRotation.d.ts +114 -0
  118. package/dist/server/oauth/refreshTokenRotation.d.ts.map +1 -0
  119. package/dist/server/oauth/refreshTokenRotation.js +344 -0
  120. package/dist/server/oauth/refreshTokenRotation.js.map +1 -0
  121. package/dist/server/oauth/security.d.ts +101 -0
  122. package/dist/server/oauth/security.d.ts.map +1 -0
  123. package/dist/server/oauth/security.js +268 -0
  124. package/dist/server/oauth/security.js.map +1 -0
  125. package/dist/server/oauth/tokenEncryption.d.ts +80 -0
  126. package/dist/server/oauth/tokenEncryption.d.ts.map +1 -0
  127. package/dist/server/oauth/tokenEncryption.js +218 -0
  128. package/dist/server/oauth/tokenEncryption.js.map +1 -0
  129. package/dist/tools/checkpoint.d.ts +35 -0
  130. package/dist/tools/checkpoint.d.ts.map +1 -0
  131. package/dist/tools/checkpoint.js +125 -0
  132. package/dist/tools/checkpoint.js.map +1 -0
  133. package/dist/tools/index.d.ts +412 -0
  134. package/dist/tools/index.d.ts.map +1 -0
  135. package/dist/tools/index.js +262 -0
  136. package/dist/tools/index.js.map +1 -0
  137. package/dist/tools/insight.d.ts +65 -0
  138. package/dist/tools/insight.d.ts.map +1 -0
  139. package/dist/tools/insight.js +190 -0
  140. package/dist/tools/insight.js.map +1 -0
  141. package/dist/tools/journey.d.ts +45 -0
  142. package/dist/tools/journey.d.ts.map +1 -0
  143. package/dist/tools/journey.js +115 -0
  144. package/dist/tools/journey.js.map +1 -0
  145. package/dist/tools/sendMessage.d.ts +6 -0
  146. package/dist/tools/sendMessage.d.ts.map +1 -0
  147. package/dist/tools/sendMessage.js +278 -0
  148. package/dist/tools/sendMessage.js.map +1 -0
  149. package/dist/tools/session.d.ts +106 -0
  150. package/dist/tools/session.d.ts.map +1 -0
  151. package/dist/tools/session.js +161 -0
  152. package/dist/tools/session.js.map +1 -0
  153. package/dist/types/auth.d.ts +37 -0
  154. package/dist/types/auth.d.ts.map +1 -0
  155. package/dist/types/auth.js +44 -0
  156. package/dist/types/auth.js.map +1 -0
  157. package/dist/types/checkpoint.d.ts +25 -0
  158. package/dist/types/checkpoint.d.ts.map +1 -0
  159. package/dist/types/checkpoint.js +8 -0
  160. package/dist/types/checkpoint.js.map +1 -0
  161. package/dist/types/insight.d.ts +83 -0
  162. package/dist/types/insight.d.ts.map +1 -0
  163. package/dist/types/insight.js +14 -0
  164. package/dist/types/insight.js.map +1 -0
  165. package/dist/types/journey.d.ts +155 -0
  166. package/dist/types/journey.d.ts.map +1 -0
  167. package/dist/types/journey.js +29 -0
  168. package/dist/types/journey.js.map +1 -0
  169. package/dist/types/session.d.ts +82 -0
  170. package/dist/types/session.d.ts.map +1 -0
  171. package/dist/types/session.js +13 -0
  172. package/dist/types/session.js.map +1 -0
  173. package/dist/utils/circuitBreaker.d.ts +86 -0
  174. package/dist/utils/circuitBreaker.d.ts.map +1 -0
  175. package/dist/utils/circuitBreaker.js +234 -0
  176. package/dist/utils/circuitBreaker.js.map +1 -0
  177. package/dist/utils/errorHandler.d.ts +101 -0
  178. package/dist/utils/errorHandler.d.ts.map +1 -0
  179. package/dist/utils/errorHandler.js +348 -0
  180. package/dist/utils/errorHandler.js.map +1 -0
  181. package/dist/utils/errors.d.ts +36 -0
  182. package/dist/utils/errors.d.ts.map +1 -0
  183. package/dist/utils/errors.js +77 -0
  184. package/dist/utils/errors.js.map +1 -0
  185. package/dist/utils/logger.d.ts +13 -0
  186. package/dist/utils/logger.d.ts.map +1 -0
  187. package/dist/utils/logger.js +49 -0
  188. package/dist/utils/logger.js.map +1 -0
  189. package/dist/utils/performanceMonitor.d.ts +106 -0
  190. package/dist/utils/performanceMonitor.d.ts.map +1 -0
  191. package/dist/utils/performanceMonitor.js +312 -0
  192. package/dist/utils/performanceMonitor.js.map +1 -0
  193. package/dist/utils/responseCache.d.ts +88 -0
  194. package/dist/utils/responseCache.d.ts.map +1 -0
  195. package/dist/utils/responseCache.js +245 -0
  196. package/dist/utils/responseCache.js.map +1 -0
  197. package/dist/utils/retryStrategy.d.ts +49 -0
  198. package/dist/utils/retryStrategy.d.ts.map +1 -0
  199. package/dist/utils/retryStrategy.js +167 -0
  200. package/dist/utils/retryStrategy.js.map +1 -0
  201. package/dist/workflows/definitions/daily-reflection.d.ts +3 -0
  202. package/dist/workflows/definitions/daily-reflection.d.ts.map +1 -0
  203. package/dist/workflows/definitions/daily-reflection.js +52 -0
  204. package/dist/workflows/definitions/daily-reflection.js.map +1 -0
  205. package/dist/workflows/definitions/gratitude-practice.d.ts +3 -0
  206. package/dist/workflows/definitions/gratitude-practice.d.ts.map +1 -0
  207. package/dist/workflows/definitions/gratitude-practice.js +52 -0
  208. package/dist/workflows/definitions/gratitude-practice.js.map +1 -0
  209. package/dist/workflows/definitions/weekly-review.d.ts +3 -0
  210. package/dist/workflows/definitions/weekly-review.d.ts.map +1 -0
  211. package/dist/workflows/definitions/weekly-review.js +74 -0
  212. package/dist/workflows/definitions/weekly-review.js.map +1 -0
  213. package/dist/workflows/engine.d.ts +21 -0
  214. package/dist/workflows/engine.d.ts.map +1 -0
  215. package/dist/workflows/engine.js +149 -0
  216. package/dist/workflows/engine.js.map +1 -0
  217. package/dist/workflows/index.d.ts +26 -0
  218. package/dist/workflows/index.d.ts.map +1 -0
  219. package/dist/workflows/index.js +14 -0
  220. package/dist/workflows/index.js.map +1 -0
  221. package/package.json +98 -0
  222. package/run-mcp-server.sh +16 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * PKCE Challenge data structure
3
+ */
4
+ export interface PKCEChallenge {
5
+ challenge: string;
6
+ method: 'S256' | 'plain';
7
+ clientId: string;
8
+ expiresAt: Date;
9
+ createdAt: Date;
10
+ }
11
+ /**
12
+ * PKCE (Proof Key for Code Exchange) Manager
13
+ * Implements RFC 7636 for OAuth 2.0 public clients
14
+ * Prevents authorization code interception attacks
15
+ */
16
+ export declare class PKCEManager {
17
+ private challenges;
18
+ private readonly MIN_VERIFIER_LENGTH;
19
+ private readonly MAX_VERIFIER_LENGTH;
20
+ private readonly CHALLENGE_TTL;
21
+ /**
22
+ * Generate a cryptographically secure code verifier
23
+ * According to RFC 7636, must be 43-128 characters
24
+ */
25
+ generateVerifier(): string;
26
+ /**
27
+ * Generate code challenge from verifier
28
+ * S256 is mandatory in OAuth 2.1, plain is deprecated
29
+ */
30
+ generateChallenge(verifier: string, method?: 'S256' | 'plain'): string;
31
+ /**
32
+ * Store PKCE challenge for later verification
33
+ */
34
+ storeChallenge(authorizationCode: string, challenge: string, method: 'S256' | 'plain', clientId: string): Promise<void>;
35
+ /**
36
+ * Validate PKCE verifier against stored challenge
37
+ * Uses constant-time comparison to prevent timing attacks
38
+ */
39
+ validatePKCE(authorizationCode: string, verifier: string, clientId: string): Promise<boolean>;
40
+ /**
41
+ * Get stored challenge (for testing/debugging)
42
+ */
43
+ getChallenge(authorizationCode: string): PKCEChallenge | undefined;
44
+ /**
45
+ * Clean up expired challenges to prevent memory leak
46
+ */
47
+ private cleanupExpiredChallenges;
48
+ /**
49
+ * Clear all challenges (for testing)
50
+ */
51
+ clearAll(): void;
52
+ /**
53
+ * Get statistics about stored challenges
54
+ */
55
+ getStats(): {
56
+ total: number;
57
+ expired: number;
58
+ };
59
+ }
60
+ export declare const pkceManager: PKCEManager;
61
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../../src/server/oauth/pkce.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAM;IAC1C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAO;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkB;IAEhD;;;OAGG;IACH,gBAAgB,IAAI,MAAM;IAc1B;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,OAAgB,GAAG,MAAM;IAe9E;;OAEG;IACG,cAAc,CAClB,iBAAiB,EAAE,MAAM,EACzB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,OAAO,EACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAgBhB;;;OAGG;IACG,YAAY,CAChB,iBAAiB,EAAE,MAAM,EACzB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC;IAqDnB;;OAEG;IACH,YAAY,CAAC,iBAAiB,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAIlE;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAgBhC;;OAEG;IACH,QAAQ,IAAI,IAAI;IAKhB;;OAEG;IACH,QAAQ,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAe/C;AAGD,eAAO,MAAM,WAAW,aAAoB,CAAC"}
@@ -0,0 +1,157 @@
1
+ import { createHash, randomBytes } from 'crypto';
2
+ import { logger } from '../../utils/logger.js';
3
+ /**
4
+ * PKCE (Proof Key for Code Exchange) Manager
5
+ * Implements RFC 7636 for OAuth 2.0 public clients
6
+ * Prevents authorization code interception attacks
7
+ */
8
+ export class PKCEManager {
9
+ challenges = new Map();
10
+ MIN_VERIFIER_LENGTH = 43;
11
+ MAX_VERIFIER_LENGTH = 128;
12
+ CHALLENGE_TTL = 10 * 60 * 1000; // 10 minutes
13
+ /**
14
+ * Generate a cryptographically secure code verifier
15
+ * According to RFC 7636, must be 43-128 characters
16
+ */
17
+ generateVerifier() {
18
+ // Generate 32 bytes (will produce 43 chars in base64url)
19
+ const buffer = randomBytes(32);
20
+ const verifier = buffer.toString('base64url');
21
+ if (verifier.length < this.MIN_VERIFIER_LENGTH ||
22
+ verifier.length > this.MAX_VERIFIER_LENGTH) {
23
+ throw new Error('Generated verifier length is out of bounds');
24
+ }
25
+ logger.debug(`Generated PKCE verifier of length ${verifier.length}`);
26
+ return verifier;
27
+ }
28
+ /**
29
+ * Generate code challenge from verifier
30
+ * S256 is mandatory in OAuth 2.1, plain is deprecated
31
+ */
32
+ generateChallenge(verifier, method = 'S256') {
33
+ if (method === 'plain') {
34
+ logger.warn('Using plain PKCE method is not recommended and will be deprecated');
35
+ return verifier;
36
+ }
37
+ // S256 = BASE64URL(SHA256(verifier))
38
+ const hash = createHash('sha256')
39
+ .update(verifier, 'ascii')
40
+ .digest('base64url');
41
+ logger.debug(`Generated S256 PKCE challenge`);
42
+ return hash;
43
+ }
44
+ /**
45
+ * Store PKCE challenge for later verification
46
+ */
47
+ async storeChallenge(authorizationCode, challenge, method, clientId) {
48
+ // Clean up expired challenges
49
+ this.cleanupExpiredChallenges();
50
+ const pkceChallenge = {
51
+ challenge,
52
+ method,
53
+ clientId,
54
+ createdAt: new Date(),
55
+ expiresAt: new Date(Date.now() + this.CHALLENGE_TTL),
56
+ };
57
+ this.challenges.set(authorizationCode, pkceChallenge);
58
+ logger.info(`Stored PKCE challenge for authorization code ${authorizationCode.substring(0, 8)}...`);
59
+ }
60
+ /**
61
+ * Validate PKCE verifier against stored challenge
62
+ * Uses constant-time comparison to prevent timing attacks
63
+ */
64
+ async validatePKCE(authorizationCode, verifier, clientId) {
65
+ const storedChallenge = this.challenges.get(authorizationCode);
66
+ if (!storedChallenge) {
67
+ logger.warn(`No PKCE challenge found for authorization code ${authorizationCode.substring(0, 8)}...`);
68
+ return false;
69
+ }
70
+ // Check expiration
71
+ if (new Date() > storedChallenge.expiresAt) {
72
+ logger.warn(`PKCE challenge expired for authorization code ${authorizationCode.substring(0, 8)}...`);
73
+ this.challenges.delete(authorizationCode);
74
+ return false;
75
+ }
76
+ // Verify client ID matches
77
+ if (storedChallenge.clientId !== clientId) {
78
+ logger.error(`Client ID mismatch in PKCE validation. Expected: ${storedChallenge.clientId}, Got: ${clientId}`);
79
+ return false;
80
+ }
81
+ // Compute challenge from provided verifier
82
+ const computedChallenge = this.generateChallenge(verifier, storedChallenge.method);
83
+ // Use constant-time comparison to prevent timing attacks
84
+ const storedBuffer = Buffer.from(storedChallenge.challenge, 'ascii');
85
+ const computedBuffer = Buffer.from(computedChallenge, 'ascii');
86
+ if (storedBuffer.length !== computedBuffer.length) {
87
+ logger.warn(`PKCE challenge length mismatch`);
88
+ return false;
89
+ }
90
+ let isValid;
91
+ try {
92
+ // crypto.timingSafeEqual throws if buffers are different lengths
93
+ isValid = storedBuffer.length === computedBuffer.length &&
94
+ crypto.timingSafeEqual(storedBuffer, computedBuffer);
95
+ }
96
+ catch {
97
+ isValid = false;
98
+ }
99
+ if (isValid) {
100
+ logger.info(`PKCE validation successful for authorization code ${authorizationCode.substring(0, 8)}...`);
101
+ // Remove used challenge
102
+ this.challenges.delete(authorizationCode);
103
+ }
104
+ else {
105
+ logger.warn(`PKCE validation failed for authorization code ${authorizationCode.substring(0, 8)}...`);
106
+ }
107
+ return isValid;
108
+ }
109
+ /**
110
+ * Get stored challenge (for testing/debugging)
111
+ */
112
+ getChallenge(authorizationCode) {
113
+ return this.challenges.get(authorizationCode);
114
+ }
115
+ /**
116
+ * Clean up expired challenges to prevent memory leak
117
+ */
118
+ cleanupExpiredChallenges() {
119
+ const now = new Date();
120
+ let cleaned = 0;
121
+ for (const [code, challenge] of this.challenges.entries()) {
122
+ if (now > challenge.expiresAt) {
123
+ this.challenges.delete(code);
124
+ cleaned++;
125
+ }
126
+ }
127
+ if (cleaned > 0) {
128
+ logger.debug(`Cleaned up ${cleaned} expired PKCE challenges`);
129
+ }
130
+ }
131
+ /**
132
+ * Clear all challenges (for testing)
133
+ */
134
+ clearAll() {
135
+ this.challenges.clear();
136
+ logger.debug('Cleared all PKCE challenges');
137
+ }
138
+ /**
139
+ * Get statistics about stored challenges
140
+ */
141
+ getStats() {
142
+ const now = new Date();
143
+ let expired = 0;
144
+ for (const challenge of this.challenges.values()) {
145
+ if (now > challenge.expiresAt) {
146
+ expired++;
147
+ }
148
+ }
149
+ return {
150
+ total: this.challenges.size,
151
+ expired,
152
+ };
153
+ }
154
+ }
155
+ // Export singleton instance
156
+ export const pkceManager = new PKCEManager();
157
+ //# sourceMappingURL=pkce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../../src/server/oauth/pkce.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,147 @@
1
+ import { JWK } from 'jose';
2
+ /**
3
+ * OAuth token response structure
4
+ */
5
+ export interface TokenResponse {
6
+ access_token: string;
7
+ token_type: string;
8
+ expires_in?: number;
9
+ refresh_token?: string;
10
+ id_token?: string;
11
+ scope?: string;
12
+ }
13
+ /**
14
+ * User information from OAuth provider
15
+ */
16
+ export interface UserInfo {
17
+ id: string;
18
+ email?: string;
19
+ email_verified?: boolean;
20
+ name?: string;
21
+ picture?: string;
22
+ locale?: string;
23
+ provider: string;
24
+ raw?: Record<string, any>;
25
+ }
26
+ /**
27
+ * ID Token claims (OpenID Connect)
28
+ */
29
+ export interface IdTokenClaims {
30
+ iss: string;
31
+ sub: string;
32
+ aud: string | string[];
33
+ exp: number;
34
+ iat: number;
35
+ nonce?: string;
36
+ email?: string;
37
+ email_verified?: boolean;
38
+ name?: string;
39
+ picture?: string;
40
+ [key: string]: any;
41
+ }
42
+ /**
43
+ * Provider configuration
44
+ */
45
+ export interface ProviderConfig {
46
+ clientId: string;
47
+ clientSecret: string;
48
+ redirectUri: string;
49
+ scopes?: string[];
50
+ additionalParams?: Record<string, string>;
51
+ }
52
+ /**
53
+ * Abstract base class for OAuth providers
54
+ * Implements common OAuth 2.0/OIDC functionality
55
+ */
56
+ export declare abstract class OAuthProvider {
57
+ abstract readonly name: string;
58
+ abstract readonly authorizationUrl: string;
59
+ abstract readonly tokenUrl: string;
60
+ abstract readonly userInfoUrl: string;
61
+ abstract readonly revokeUrl?: string;
62
+ abstract readonly jwksUrl?: string;
63
+ protected config: ProviderConfig;
64
+ private jwksCache;
65
+ private readonly JWKS_CACHE_TTL;
66
+ constructor(config: ProviderConfig);
67
+ /**
68
+ * Build authorization URL with required parameters
69
+ */
70
+ buildAuthorizationUrl(params: {
71
+ state: string;
72
+ codeChallenge?: string;
73
+ codeChallengeMethod?: string;
74
+ nonce?: string;
75
+ scope?: string;
76
+ additionalParams?: Record<string, string>;
77
+ }): string;
78
+ /**
79
+ * Exchange authorization code for tokens
80
+ */
81
+ exchangeCode(code: string, codeVerifier?: string): Promise<TokenResponse>;
82
+ /**
83
+ * Refresh access token
84
+ */
85
+ refreshToken(refreshToken: string): Promise<TokenResponse>;
86
+ /**
87
+ * Get user information from provider
88
+ */
89
+ getUserInfo(accessToken: string): Promise<UserInfo>;
90
+ /**
91
+ * Revoke token (if supported by provider)
92
+ */
93
+ revokeToken(token: string, tokenType?: 'access_token' | 'refresh_token'): Promise<void>;
94
+ /**
95
+ * Validate ID token (OpenID Connect)
96
+ */
97
+ protected validateIdToken(idToken: string): Promise<IdTokenClaims>;
98
+ /**
99
+ * Get JWKS from provider (with caching)
100
+ */
101
+ protected getJWKS(): Promise<{
102
+ keys: JWK[];
103
+ }>;
104
+ /**
105
+ * Validate redirect URI
106
+ */
107
+ protected validateRedirectUri(uri: string): boolean;
108
+ /**
109
+ * Get default scopes for this provider
110
+ */
111
+ protected abstract getDefaultScopes(): string[];
112
+ /**
113
+ * Get expected issuer for ID token validation
114
+ */
115
+ protected abstract getExpectedIssuer(): string;
116
+ /**
117
+ * Normalize user info to common format
118
+ */
119
+ protected abstract normalizeUserInfo(data: any): UserInfo;
120
+ /**
121
+ * Additional ID token claims validation
122
+ */
123
+ protected validateIdTokenClaims(claims: IdTokenClaims): void;
124
+ /**
125
+ * Handle provider-specific errors
126
+ */
127
+ protected handleProviderError(error: any): never;
128
+ }
129
+ /**
130
+ * Provider factory
131
+ */
132
+ export declare class ProviderFactory {
133
+ private static providers;
134
+ /**
135
+ * Register a provider
136
+ */
137
+ static register(name: string, providerClass: typeof OAuthProvider): void;
138
+ /**
139
+ * Create provider instance
140
+ */
141
+ static create(name: string, config: ProviderConfig): OAuthProvider;
142
+ /**
143
+ * Get list of registered providers
144
+ */
145
+ static getProviders(): string[];
146
+ }
147
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/server/oauth/providers/base.ts"],"names":[],"mappings":"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"}