@mcp-z/oauth-microsoft 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 (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +98 -0
  3. package/dist/cjs/index.d.cts +16 -0
  4. package/dist/cjs/index.d.ts +16 -0
  5. package/dist/cjs/index.js +112 -0
  6. package/dist/cjs/index.js.map +1 -0
  7. package/dist/cjs/lib/dcr-router.d.cts +44 -0
  8. package/dist/cjs/lib/dcr-router.d.ts +44 -0
  9. package/dist/cjs/lib/dcr-router.js +1227 -0
  10. package/dist/cjs/lib/dcr-router.js.map +1 -0
  11. package/dist/cjs/lib/dcr-utils.d.cts +160 -0
  12. package/dist/cjs/lib/dcr-utils.d.ts +160 -0
  13. package/dist/cjs/lib/dcr-utils.js +860 -0
  14. package/dist/cjs/lib/dcr-utils.js.map +1 -0
  15. package/dist/cjs/lib/dcr-verify.d.cts +53 -0
  16. package/dist/cjs/lib/dcr-verify.d.ts +53 -0
  17. package/dist/cjs/lib/dcr-verify.js +193 -0
  18. package/dist/cjs/lib/dcr-verify.js.map +1 -0
  19. package/dist/cjs/lib/fetch-with-timeout.d.cts +14 -0
  20. package/dist/cjs/lib/fetch-with-timeout.d.ts +14 -0
  21. package/dist/cjs/lib/fetch-with-timeout.js +257 -0
  22. package/dist/cjs/lib/fetch-with-timeout.js.map +1 -0
  23. package/dist/cjs/lib/token-verifier.d.cts +44 -0
  24. package/dist/cjs/lib/token-verifier.d.ts +44 -0
  25. package/dist/cjs/lib/token-verifier.js +253 -0
  26. package/dist/cjs/lib/token-verifier.js.map +1 -0
  27. package/dist/cjs/package.json +1 -0
  28. package/dist/cjs/providers/dcr.d.cts +110 -0
  29. package/dist/cjs/providers/dcr.d.ts +110 -0
  30. package/dist/cjs/providers/dcr.js +600 -0
  31. package/dist/cjs/providers/dcr.js.map +1 -0
  32. package/dist/cjs/providers/device-code.d.cts +179 -0
  33. package/dist/cjs/providers/device-code.d.ts +179 -0
  34. package/dist/cjs/providers/device-code.js +896 -0
  35. package/dist/cjs/providers/device-code.js.map +1 -0
  36. package/dist/cjs/providers/loopback-oauth.d.cts +125 -0
  37. package/dist/cjs/providers/loopback-oauth.d.ts +125 -0
  38. package/dist/cjs/providers/loopback-oauth.js +1325 -0
  39. package/dist/cjs/providers/loopback-oauth.js.map +1 -0
  40. package/dist/cjs/schemas/index.d.cts +20 -0
  41. package/dist/cjs/schemas/index.d.ts +20 -0
  42. package/dist/cjs/schemas/index.js +37 -0
  43. package/dist/cjs/schemas/index.js.map +1 -0
  44. package/dist/cjs/setup/config.d.cts +113 -0
  45. package/dist/cjs/setup/config.d.ts +113 -0
  46. package/dist/cjs/setup/config.js +246 -0
  47. package/dist/cjs/setup/config.js.map +1 -0
  48. package/dist/cjs/types.d.cts +188 -0
  49. package/dist/cjs/types.d.ts +188 -0
  50. package/dist/cjs/types.js +18 -0
  51. package/dist/cjs/types.js.map +1 -0
  52. package/dist/esm/index.d.ts +16 -0
  53. package/dist/esm/index.js +16 -0
  54. package/dist/esm/index.js.map +1 -0
  55. package/dist/esm/lib/dcr-router.d.ts +44 -0
  56. package/dist/esm/lib/dcr-router.js +556 -0
  57. package/dist/esm/lib/dcr-router.js.map +1 -0
  58. package/dist/esm/lib/dcr-utils.d.ts +160 -0
  59. package/dist/esm/lib/dcr-utils.js +270 -0
  60. package/dist/esm/lib/dcr-utils.js.map +1 -0
  61. package/dist/esm/lib/dcr-verify.d.ts +53 -0
  62. package/dist/esm/lib/dcr-verify.js +53 -0
  63. package/dist/esm/lib/dcr-verify.js.map +1 -0
  64. package/dist/esm/lib/fetch-with-timeout.d.ts +14 -0
  65. package/dist/esm/lib/fetch-with-timeout.js +30 -0
  66. package/dist/esm/lib/fetch-with-timeout.js.map +1 -0
  67. package/dist/esm/lib/token-verifier.d.ts +44 -0
  68. package/dist/esm/lib/token-verifier.js +53 -0
  69. package/dist/esm/lib/token-verifier.js.map +1 -0
  70. package/dist/esm/package.json +1 -0
  71. package/dist/esm/providers/dcr.d.ts +110 -0
  72. package/dist/esm/providers/dcr.js +235 -0
  73. package/dist/esm/providers/dcr.js.map +1 -0
  74. package/dist/esm/providers/device-code.d.ts +179 -0
  75. package/dist/esm/providers/device-code.js +417 -0
  76. package/dist/esm/providers/device-code.js.map +1 -0
  77. package/dist/esm/providers/loopback-oauth.d.ts +125 -0
  78. package/dist/esm/providers/loopback-oauth.js +643 -0
  79. package/dist/esm/providers/loopback-oauth.js.map +1 -0
  80. package/dist/esm/schemas/index.d.ts +20 -0
  81. package/dist/esm/schemas/index.js +18 -0
  82. package/dist/esm/schemas/index.js.map +1 -0
  83. package/dist/esm/setup/config.d.ts +113 -0
  84. package/dist/esm/setup/config.js +268 -0
  85. package/dist/esm/setup/config.js.map +1 -0
  86. package/dist/esm/types.d.ts +188 -0
  87. package/dist/esm/types.js +8 -0
  88. package/dist/esm/types.js.map +1 -0
  89. package/package.json +87 -0
@@ -0,0 +1,44 @@
1
+ /**
2
+ * DCR Token Verifier
3
+ *
4
+ * Validates bearer tokens by calling Authorization Server's verification endpoint.
5
+ * Implements proper AS/RS separation - Resource Server doesn't access token storage.
6
+ */
7
+ import type { ProviderTokens } from '@mcp-z/oauth';
8
+ /**
9
+ * Authentication information from token verification
10
+ */
11
+ export interface AuthInfo {
12
+ /** Bearer access token */
13
+ token: string;
14
+ /** Client ID that owns the token */
15
+ clientId: string;
16
+ /** Granted scopes */
17
+ scopes: string[];
18
+ /** Token expiration timestamp (milliseconds since epoch) */
19
+ expiresAt: number;
20
+ /** Microsoft provider tokens (if available) */
21
+ providerTokens?: ProviderTokens;
22
+ }
23
+ /**
24
+ * DCR Token Verifier validates access tokens via Authorization Server
25
+ *
26
+ * This implements proper OAuth 2.0 architecture where the Resource Server
27
+ * (MCP server) validates tokens by calling the Authorization Server's
28
+ * verification endpoint rather than accessing token storage directly.
29
+ */
30
+ export declare class DcrTokenVerifier {
31
+ private verifyUrl;
32
+ /**
33
+ * @param verifyUrl - Authorization Server's /oauth/verify endpoint URL
34
+ */
35
+ constructor(verifyUrl: string);
36
+ /**
37
+ * Verify an access token by calling the Authorization Server
38
+ *
39
+ * @param token - Bearer access token to validate
40
+ * @returns AuthInfo with token metadata and provider tokens
41
+ * @throws Error if token is invalid or verification fails
42
+ */
43
+ verifyAccessToken(token: string): Promise<AuthInfo>;
44
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * DCR Token Verifier
3
+ *
4
+ * Validates bearer tokens by calling Authorization Server's verification endpoint.
5
+ * Implements proper AS/RS separation - Resource Server doesn't access token storage.
6
+ */
7
+ import type { ProviderTokens } from '@mcp-z/oauth';
8
+ /**
9
+ * Authentication information from token verification
10
+ */
11
+ export interface AuthInfo {
12
+ /** Bearer access token */
13
+ token: string;
14
+ /** Client ID that owns the token */
15
+ clientId: string;
16
+ /** Granted scopes */
17
+ scopes: string[];
18
+ /** Token expiration timestamp (milliseconds since epoch) */
19
+ expiresAt: number;
20
+ /** Microsoft provider tokens (if available) */
21
+ providerTokens?: ProviderTokens;
22
+ }
23
+ /**
24
+ * DCR Token Verifier validates access tokens via Authorization Server
25
+ *
26
+ * This implements proper OAuth 2.0 architecture where the Resource Server
27
+ * (MCP server) validates tokens by calling the Authorization Server's
28
+ * verification endpoint rather than accessing token storage directly.
29
+ */
30
+ export declare class DcrTokenVerifier {
31
+ private verifyUrl;
32
+ /**
33
+ * @param verifyUrl - Authorization Server's /oauth/verify endpoint URL
34
+ */
35
+ constructor(verifyUrl: string);
36
+ /**
37
+ * Verify an access token by calling the Authorization Server
38
+ *
39
+ * @param token - Bearer access token to validate
40
+ * @returns AuthInfo with token metadata and provider tokens
41
+ * @throws Error if token is invalid or verification fails
42
+ */
43
+ verifyAccessToken(token: string): Promise<AuthInfo>;
44
+ }
@@ -0,0 +1,253 @@
1
+ /**
2
+ * DCR Token Verifier
3
+ *
4
+ * Validates bearer tokens by calling Authorization Server's verification endpoint.
5
+ * Implements proper AS/RS separation - Resource Server doesn't access token storage.
6
+ */ "use strict";
7
+ Object.defineProperty(exports, "__esModule", {
8
+ value: true
9
+ });
10
+ Object.defineProperty(exports, "DcrTokenVerifier", {
11
+ enumerable: true,
12
+ get: function() {
13
+ return DcrTokenVerifier;
14
+ }
15
+ });
16
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
17
+ try {
18
+ var info = gen[key](arg);
19
+ var value = info.value;
20
+ } catch (error) {
21
+ reject(error);
22
+ return;
23
+ }
24
+ if (info.done) {
25
+ resolve(value);
26
+ } else {
27
+ Promise.resolve(value).then(_next, _throw);
28
+ }
29
+ }
30
+ function _async_to_generator(fn) {
31
+ return function() {
32
+ var self = this, args = arguments;
33
+ return new Promise(function(resolve, reject) {
34
+ var gen = fn.apply(self, args);
35
+ function _next(value) {
36
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
37
+ }
38
+ function _throw(err) {
39
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
40
+ }
41
+ _next(undefined);
42
+ });
43
+ };
44
+ }
45
+ function _class_call_check(instance, Constructor) {
46
+ if (!(instance instanceof Constructor)) {
47
+ throw new TypeError("Cannot call a class as a function");
48
+ }
49
+ }
50
+ function _instanceof(left, right) {
51
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
52
+ return !!right[Symbol.hasInstance](left);
53
+ } else {
54
+ return left instanceof right;
55
+ }
56
+ }
57
+ function _ts_generator(thisArg, body) {
58
+ var f, y, t, _ = {
59
+ label: 0,
60
+ sent: function() {
61
+ if (t[0] & 1) throw t[1];
62
+ return t[1];
63
+ },
64
+ trys: [],
65
+ ops: []
66
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
67
+ return d(g, "next", {
68
+ value: verb(0)
69
+ }), d(g, "throw", {
70
+ value: verb(1)
71
+ }), d(g, "return", {
72
+ value: verb(2)
73
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
74
+ value: function() {
75
+ return this;
76
+ }
77
+ }), g;
78
+ function verb(n) {
79
+ return function(v) {
80
+ return step([
81
+ n,
82
+ v
83
+ ]);
84
+ };
85
+ }
86
+ function step(op) {
87
+ if (f) throw new TypeError("Generator is already executing.");
88
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
89
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
90
+ if (y = 0, t) op = [
91
+ op[0] & 2,
92
+ t.value
93
+ ];
94
+ switch(op[0]){
95
+ case 0:
96
+ case 1:
97
+ t = op;
98
+ break;
99
+ case 4:
100
+ _.label++;
101
+ return {
102
+ value: op[1],
103
+ done: false
104
+ };
105
+ case 5:
106
+ _.label++;
107
+ y = op[1];
108
+ op = [
109
+ 0
110
+ ];
111
+ continue;
112
+ case 7:
113
+ op = _.ops.pop();
114
+ _.trys.pop();
115
+ continue;
116
+ default:
117
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
118
+ _ = 0;
119
+ continue;
120
+ }
121
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
122
+ _.label = op[1];
123
+ break;
124
+ }
125
+ if (op[0] === 6 && _.label < t[1]) {
126
+ _.label = t[1];
127
+ t = op;
128
+ break;
129
+ }
130
+ if (t && _.label < t[2]) {
131
+ _.label = t[2];
132
+ _.ops.push(op);
133
+ break;
134
+ }
135
+ if (t[2]) _.ops.pop();
136
+ _.trys.pop();
137
+ continue;
138
+ }
139
+ op = body.call(thisArg, _);
140
+ } catch (e) {
141
+ op = [
142
+ 6,
143
+ e
144
+ ];
145
+ y = 0;
146
+ } finally{
147
+ f = t = 0;
148
+ }
149
+ if (op[0] & 5) throw op[1];
150
+ return {
151
+ value: op[0] ? op[1] : void 0,
152
+ done: true
153
+ };
154
+ }
155
+ }
156
+ var DcrTokenVerifier = /*#__PURE__*/ function() {
157
+ "use strict";
158
+ function DcrTokenVerifier(verifyUrl) {
159
+ _class_call_check(this, DcrTokenVerifier);
160
+ this.verifyUrl = verifyUrl;
161
+ }
162
+ var _proto = DcrTokenVerifier.prototype;
163
+ /**
164
+ * Verify an access token by calling the Authorization Server
165
+ *
166
+ * @param token - Bearer access token to validate
167
+ * @returns AuthInfo with token metadata and provider tokens
168
+ * @throws Error if token is invalid or verification fails
169
+ */ _proto.verifyAccessToken = function verifyAccessToken(token) {
170
+ return _async_to_generator(function() {
171
+ var response, errorMessage, _ref, _error_error_description, _$error, unused, authInfo, error;
172
+ return _ts_generator(this, function(_state) {
173
+ switch(_state.label){
174
+ case 0:
175
+ _state.trys.push([
176
+ 0,
177
+ 8,
178
+ ,
179
+ 9
180
+ ]);
181
+ return [
182
+ 4,
183
+ fetch(this.verifyUrl, {
184
+ method: 'GET',
185
+ headers: {
186
+ Authorization: "Bearer ".concat(token)
187
+ }
188
+ })
189
+ ];
190
+ case 1:
191
+ response = _state.sent();
192
+ if (!!response.ok) return [
193
+ 3,
194
+ 6
195
+ ];
196
+ errorMessage = 'Unknown error';
197
+ _state.label = 2;
198
+ case 2:
199
+ _state.trys.push([
200
+ 2,
201
+ 4,
202
+ ,
203
+ 5
204
+ ]);
205
+ return [
206
+ 4,
207
+ response.json()
208
+ ];
209
+ case 3:
210
+ _$error = _state.sent();
211
+ errorMessage = (_ref = (_error_error_description = _$error.error_description) !== null && _error_error_description !== void 0 ? _error_error_description : _$error.error) !== null && _ref !== void 0 ? _ref : errorMessage;
212
+ return [
213
+ 3,
214
+ 5
215
+ ];
216
+ case 4:
217
+ unused = _state.sent();
218
+ // Failed to parse error JSON, use status text
219
+ errorMessage = response.statusText;
220
+ return [
221
+ 3,
222
+ 5
223
+ ];
224
+ case 5:
225
+ throw new Error("Token verification failed: ".concat(errorMessage));
226
+ case 6:
227
+ return [
228
+ 4,
229
+ response.json()
230
+ ];
231
+ case 7:
232
+ authInfo = _state.sent();
233
+ return [
234
+ 2,
235
+ authInfo
236
+ ];
237
+ case 8:
238
+ error = _state.sent();
239
+ if (_instanceof(error, Error)) {
240
+ throw error;
241
+ }
242
+ throw new Error("Token verification failed: ".concat(String(error)));
243
+ case 9:
244
+ return [
245
+ 2
246
+ ];
247
+ }
248
+ });
249
+ }).call(this);
250
+ };
251
+ return DcrTokenVerifier;
252
+ }();
253
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/oauth/oauth-microsoft/src/lib/token-verifier.ts"],"sourcesContent":["/**\n * DCR Token Verifier\n *\n * Validates bearer tokens by calling Authorization Server's verification endpoint.\n * Implements proper AS/RS separation - Resource Server doesn't access token storage.\n */\n\nimport type { ProviderTokens } from '@mcp-z/oauth';\n\n/**\n * Authentication information from token verification\n */\nexport interface AuthInfo {\n /** Bearer access token */\n token: string;\n\n /** Client ID that owns the token */\n clientId: string;\n\n /** Granted scopes */\n scopes: string[];\n\n /** Token expiration timestamp (milliseconds since epoch) */\n expiresAt: number;\n\n /** Microsoft provider tokens (if available) */\n providerTokens?: ProviderTokens;\n}\n\n/**\n * DCR Token Verifier validates access tokens via Authorization Server\n *\n * This implements proper OAuth 2.0 architecture where the Resource Server\n * (MCP server) validates tokens by calling the Authorization Server's\n * verification endpoint rather than accessing token storage directly.\n */\nexport class DcrTokenVerifier {\n private verifyUrl: string;\n\n /**\n * @param verifyUrl - Authorization Server's /oauth/verify endpoint URL\n */\n constructor(verifyUrl: string) {\n this.verifyUrl = verifyUrl;\n }\n\n /**\n * Verify an access token by calling the Authorization Server\n *\n * @param token - Bearer access token to validate\n * @returns AuthInfo with token metadata and provider tokens\n * @throws Error if token is invalid or verification fails\n */\n async verifyAccessToken(token: string): Promise<AuthInfo> {\n try {\n const response = await fetch(this.verifyUrl, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n let errorMessage = 'Unknown error';\n try {\n const error = await response.json();\n errorMessage = (error as { error_description?: string; error?: string }).error_description ?? (error as { error?: string }).error ?? errorMessage;\n } catch {\n // Failed to parse error JSON, use status text\n errorMessage = response.statusText;\n }\n throw new Error(`Token verification failed: ${errorMessage}`);\n }\n\n const authInfo = (await response.json()) as AuthInfo;\n return authInfo;\n } catch (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error(`Token verification failed: ${String(error)}`);\n }\n }\n}\n"],"names":["DcrTokenVerifier","verifyUrl","verifyAccessToken","token","response","errorMessage","error","authInfo","fetch","method","headers","Authorization","ok","json","error_description","statusText","Error","String"],"mappings":"AAAA;;;;;CAKC;;;;+BA+BYA;;;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAN,IAAA,AAAMA,iCAAN;;aAAMA,iBAMCC,SAAiB;gCANlBD;QAOT,IAAI,CAACC,SAAS,GAAGA;;iBAPRD;IAUX;;;;;;GAMC,GACD,OAAME,iBA6BL,GA7BD,SAAMA,kBAAkBC,KAAa;;gBAE3BC,UAQAC,cAGa,MAAA,0BADTC,iBASJC,UAECD;;;;;;;;;;wBArBU;;4BAAME,MAAM,IAAI,CAACP,SAAS,EAAE;gCAC3CQ,QAAQ;gCACRC,SAAS;oCACPC,eAAe,AAAC,UAAe,OAANR;gCAC3B;4BACF;;;wBALMC,WAAW;6BAOb,CAACA,SAASQ,EAAE,EAAZ;;;;wBACEP,eAAe;;;;;;;;;wBAEH;;4BAAMD,SAASS,IAAI;;;wBAA3BP,UAAQ;wBACdD,gBAAe,QAAA,2BAAA,AAACC,QAAyDQ,iBAAiB,cAA3E,sCAAA,2BAA+E,AAACR,QAA6BA,KAAK,cAAlH,kBAAA,OAAsHD;;;;;;;wBAErI,8CAA8C;wBAC9CA,eAAeD,SAASW,UAAU;;;;;;wBAEpC,MAAM,IAAIC,MAAM,AAAC,8BAA0C,OAAbX;;wBAG9B;;4BAAMD,SAASS,IAAI;;;wBAA/BN,WAAY;wBAClB;;4BAAOA;;;wBACAD;wBACP,IAAIA,AAAK,YAALA,OAAiBU,QAAO;4BAC1B,MAAMV;wBACR;wBACA,MAAM,IAAIU,MAAM,AAAC,8BAA2C,OAAdC,OAAOX;;;;;;;QAEzD;;WA9CWN"}
@@ -0,0 +1 @@
1
+ { "type": "commonjs" }
@@ -0,0 +1,110 @@
1
+ /**
2
+ * DCR Provider - Stateless Dynamic Client Registration Provider
3
+ *
4
+ * Implements stateless provider pattern where provider tokens are received from
5
+ * token verification context rather than managed by the provider itself.
6
+ *
7
+ * Use case: MCP HTTP servers with DCR authentication where client manages tokens
8
+ * and provider only handles Microsoft Graph API calls with provided credentials.
9
+ */
10
+ import type { ProviderTokens } from '@mcp-z/oauth';
11
+ import type { Logger, MicrosoftAuthProvider } from '../types.js';
12
+ /**
13
+ * DCR Provider configuration
14
+ */
15
+ export interface DcrOAuthProviderConfig {
16
+ /** Microsoft application client ID */
17
+ clientId: string;
18
+ /** Microsoft application client secret (optional for public clients) */
19
+ clientSecret?: string;
20
+ /** Azure AD tenant ID */
21
+ tenantId: string;
22
+ /** OAuth scopes */
23
+ scope: string;
24
+ /** Custom token endpoint URL (for testing, defaults to Microsoft OAuth endpoint) */
25
+ tokenUrl?: string;
26
+ /** DCR token verification endpoint URL (e.g., http://localhost:3000/oauth/verify) */
27
+ verifyEndpoint: string;
28
+ /** Logger for auth operations */
29
+ logger: Logger;
30
+ }
31
+ /**
32
+ * DCR Provider - Stateless OAuth provider for Dynamic Client Registration
33
+ *
34
+ * Unlike LoopbackOAuthProvider which manages token storage, DcrOAuthProvider is stateless:
35
+ * - Receives provider tokens from verification context (HTTP bearer auth)
36
+ * - Creates auth providers on-demand from tokens
37
+ * - Handles token refresh using Microsoft OAuth
38
+ * - No token storage dependency
39
+ *
40
+ * Pattern:
41
+ * ```typescript
42
+ * const provider = new DcrOAuthProvider(config);
43
+ * const auth = provider.toAuthProvider(providerTokens);
44
+ * const accessToken = await auth.getAccessToken();
45
+ * ```
46
+ */
47
+ export declare class DcrOAuthProvider {
48
+ private config;
49
+ private emailCache;
50
+ constructor(config: DcrOAuthProviderConfig);
51
+ /**
52
+ * Create Microsoft Graph auth provider from provider tokens
53
+ *
54
+ * This is the core stateless pattern - provider receives tokens from context
55
+ * (token verification, HTTP request) and creates auth provider on-demand.
56
+ *
57
+ * @param tokens - Provider tokens (Microsoft access/refresh tokens)
58
+ * @returns Microsoft Graph-compatible auth provider
59
+ */
60
+ toAuthProvider(tokens: ProviderTokens): MicrosoftAuthProvider;
61
+ /**
62
+ * Check if token is still valid (with 1 minute buffer)
63
+ */
64
+ private isTokenValid;
65
+ /**
66
+ * Refresh Microsoft access token using refresh token
67
+ *
68
+ * @param refreshToken - Microsoft refresh token
69
+ * @returns New provider tokens
70
+ */
71
+ refreshAccessToken(refreshToken: string): Promise<ProviderTokens>;
72
+ /**
73
+ * Get user email from Microsoft Graph API (with caching)
74
+ *
75
+ * @param tokens - Provider tokens to use for API call
76
+ * @returns User's email address
77
+ */
78
+ getUserEmail(tokens: ProviderTokens): Promise<string>;
79
+ /**
80
+ * Auth middleware for HTTP servers with DCR bearer auth
81
+ * Validates bearer tokens and enriches extra with provider tokens
82
+ *
83
+ * Pattern:
84
+ * ```typescript
85
+ * const provider = new DcrOAuthProvider({ ..., verifyEndpoint: 'http://localhost:3000/oauth/verify' });
86
+ * const middleware = provider.authMiddleware();
87
+ * const tools = toolFactories.map(f => f()).map(middleware.withToolAuth);
88
+ * const resources = resourceFactories.map(f => f()).map(middleware.withResourceAuth);
89
+ * const prompts = promptFactories.map(f => f()).map(middleware.withPromptAuth);
90
+ * ```
91
+ */
92
+ authMiddleware(): {
93
+ withToolAuth: <T extends {
94
+ name: string;
95
+ config: unknown;
96
+ handler: unknown;
97
+ }>(module: T) => T;
98
+ withResourceAuth: <T extends {
99
+ name: string;
100
+ template?: unknown;
101
+ config?: unknown;
102
+ handler: unknown;
103
+ }>(module: T) => T;
104
+ withPromptAuth: <T extends {
105
+ name: string;
106
+ config: unknown;
107
+ handler: unknown;
108
+ }>(module: T) => T;
109
+ };
110
+ }
@@ -0,0 +1,110 @@
1
+ /**
2
+ * DCR Provider - Stateless Dynamic Client Registration Provider
3
+ *
4
+ * Implements stateless provider pattern where provider tokens are received from
5
+ * token verification context rather than managed by the provider itself.
6
+ *
7
+ * Use case: MCP HTTP servers with DCR authentication where client manages tokens
8
+ * and provider only handles Microsoft Graph API calls with provided credentials.
9
+ */
10
+ import type { ProviderTokens } from '@mcp-z/oauth';
11
+ import type { Logger, MicrosoftAuthProvider } from '../types.js';
12
+ /**
13
+ * DCR Provider configuration
14
+ */
15
+ export interface DcrOAuthProviderConfig {
16
+ /** Microsoft application client ID */
17
+ clientId: string;
18
+ /** Microsoft application client secret (optional for public clients) */
19
+ clientSecret?: string;
20
+ /** Azure AD tenant ID */
21
+ tenantId: string;
22
+ /** OAuth scopes */
23
+ scope: string;
24
+ /** Custom token endpoint URL (for testing, defaults to Microsoft OAuth endpoint) */
25
+ tokenUrl?: string;
26
+ /** DCR token verification endpoint URL (e.g., http://localhost:3000/oauth/verify) */
27
+ verifyEndpoint: string;
28
+ /** Logger for auth operations */
29
+ logger: Logger;
30
+ }
31
+ /**
32
+ * DCR Provider - Stateless OAuth provider for Dynamic Client Registration
33
+ *
34
+ * Unlike LoopbackOAuthProvider which manages token storage, DcrOAuthProvider is stateless:
35
+ * - Receives provider tokens from verification context (HTTP bearer auth)
36
+ * - Creates auth providers on-demand from tokens
37
+ * - Handles token refresh using Microsoft OAuth
38
+ * - No token storage dependency
39
+ *
40
+ * Pattern:
41
+ * ```typescript
42
+ * const provider = new DcrOAuthProvider(config);
43
+ * const auth = provider.toAuthProvider(providerTokens);
44
+ * const accessToken = await auth.getAccessToken();
45
+ * ```
46
+ */
47
+ export declare class DcrOAuthProvider {
48
+ private config;
49
+ private emailCache;
50
+ constructor(config: DcrOAuthProviderConfig);
51
+ /**
52
+ * Create Microsoft Graph auth provider from provider tokens
53
+ *
54
+ * This is the core stateless pattern - provider receives tokens from context
55
+ * (token verification, HTTP request) and creates auth provider on-demand.
56
+ *
57
+ * @param tokens - Provider tokens (Microsoft access/refresh tokens)
58
+ * @returns Microsoft Graph-compatible auth provider
59
+ */
60
+ toAuthProvider(tokens: ProviderTokens): MicrosoftAuthProvider;
61
+ /**
62
+ * Check if token is still valid (with 1 minute buffer)
63
+ */
64
+ private isTokenValid;
65
+ /**
66
+ * Refresh Microsoft access token using refresh token
67
+ *
68
+ * @param refreshToken - Microsoft refresh token
69
+ * @returns New provider tokens
70
+ */
71
+ refreshAccessToken(refreshToken: string): Promise<ProviderTokens>;
72
+ /**
73
+ * Get user email from Microsoft Graph API (with caching)
74
+ *
75
+ * @param tokens - Provider tokens to use for API call
76
+ * @returns User's email address
77
+ */
78
+ getUserEmail(tokens: ProviderTokens): Promise<string>;
79
+ /**
80
+ * Auth middleware for HTTP servers with DCR bearer auth
81
+ * Validates bearer tokens and enriches extra with provider tokens
82
+ *
83
+ * Pattern:
84
+ * ```typescript
85
+ * const provider = new DcrOAuthProvider({ ..., verifyEndpoint: 'http://localhost:3000/oauth/verify' });
86
+ * const middleware = provider.authMiddleware();
87
+ * const tools = toolFactories.map(f => f()).map(middleware.withToolAuth);
88
+ * const resources = resourceFactories.map(f => f()).map(middleware.withResourceAuth);
89
+ * const prompts = promptFactories.map(f => f()).map(middleware.withPromptAuth);
90
+ * ```
91
+ */
92
+ authMiddleware(): {
93
+ withToolAuth: <T extends {
94
+ name: string;
95
+ config: unknown;
96
+ handler: unknown;
97
+ }>(module: T) => T;
98
+ withResourceAuth: <T extends {
99
+ name: string;
100
+ template?: unknown;
101
+ config?: unknown;
102
+ handler: unknown;
103
+ }>(module: T) => T;
104
+ withPromptAuth: <T extends {
105
+ name: string;
106
+ config: unknown;
107
+ handler: unknown;
108
+ }>(module: T) => T;
109
+ };
110
+ }