@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,1227 @@
1
+ /**
2
+ * DCR Router - OAuth 2.0 Authorization Server
3
+ *
4
+ * Implements OAuth 2.0 Dynamic Client Registration Protocol (RFC 7591)
5
+ * and OAuth 2.0 Authorization Server endpoints (RFC 6749, RFC 8414, RFC 9728).
6
+ *
7
+ * Endpoints:
8
+ * - GET /.well-known/oauth-authorization-server (RFC 8414 metadata)
9
+ * - GET /.well-known/oauth-protected-resource (RFC 9728 metadata - root)
10
+ * - GET /.well-known/oauth-protected-resource/mcp (RFC 9728 metadata - sub-path)
11
+ * - POST /oauth/register (RFC 7591 client registration)
12
+ * - GET /oauth/authorize (RFC 6749 authorization endpoint)
13
+ * - POST /oauth/token (RFC 6749 token endpoint)
14
+ * - POST /oauth/revoke (RFC 7009 token revocation)
15
+ * - GET /oauth/verify (token verification for Resource Server)
16
+ */ "use strict";
17
+ Object.defineProperty(exports, "__esModule", {
18
+ value: true
19
+ });
20
+ Object.defineProperty(exports, "createDcrRouter", {
21
+ enumerable: true,
22
+ get: function() {
23
+ return createDcrRouter;
24
+ }
25
+ });
26
+ var _crypto = require("crypto");
27
+ var _express = /*#__PURE__*/ _interop_require_default(require("express"));
28
+ var _dcrts = require("../providers/dcr.js");
29
+ var _dcrutilsts = /*#__PURE__*/ _interop_require_wildcard(require("./dcr-utils.js"));
30
+ function _array_like_to_array(arr, len) {
31
+ if (len == null || len > arr.length) len = arr.length;
32
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
33
+ return arr2;
34
+ }
35
+ function _array_with_holes(arr) {
36
+ if (Array.isArray(arr)) return arr;
37
+ }
38
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
39
+ try {
40
+ var info = gen[key](arg);
41
+ var value = info.value;
42
+ } catch (error) {
43
+ reject(error);
44
+ return;
45
+ }
46
+ if (info.done) {
47
+ resolve(value);
48
+ } else {
49
+ Promise.resolve(value).then(_next, _throw);
50
+ }
51
+ }
52
+ function _async_to_generator(fn) {
53
+ return function() {
54
+ var self = this, args = arguments;
55
+ return new Promise(function(resolve, reject) {
56
+ var gen = fn.apply(self, args);
57
+ function _next(value) {
58
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
59
+ }
60
+ function _throw(err) {
61
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
62
+ }
63
+ _next(undefined);
64
+ });
65
+ };
66
+ }
67
+ function _define_property(obj, key, value) {
68
+ if (key in obj) {
69
+ Object.defineProperty(obj, key, {
70
+ value: value,
71
+ enumerable: true,
72
+ configurable: true,
73
+ writable: true
74
+ });
75
+ } else {
76
+ obj[key] = value;
77
+ }
78
+ return obj;
79
+ }
80
+ function _instanceof(left, right) {
81
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
82
+ return !!right[Symbol.hasInstance](left);
83
+ } else {
84
+ return left instanceof right;
85
+ }
86
+ }
87
+ function _interop_require_default(obj) {
88
+ return obj && obj.__esModule ? obj : {
89
+ default: obj
90
+ };
91
+ }
92
+ function _getRequireWildcardCache(nodeInterop) {
93
+ if (typeof WeakMap !== "function") return null;
94
+ var cacheBabelInterop = new WeakMap();
95
+ var cacheNodeInterop = new WeakMap();
96
+ return (_getRequireWildcardCache = function(nodeInterop) {
97
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
98
+ })(nodeInterop);
99
+ }
100
+ function _interop_require_wildcard(obj, nodeInterop) {
101
+ if (!nodeInterop && obj && obj.__esModule) {
102
+ return obj;
103
+ }
104
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
105
+ return {
106
+ default: obj
107
+ };
108
+ }
109
+ var cache = _getRequireWildcardCache(nodeInterop);
110
+ if (cache && cache.has(obj)) {
111
+ return cache.get(obj);
112
+ }
113
+ var newObj = {
114
+ __proto__: null
115
+ };
116
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
117
+ for(var key in obj){
118
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
119
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
120
+ if (desc && (desc.get || desc.set)) {
121
+ Object.defineProperty(newObj, key, desc);
122
+ } else {
123
+ newObj[key] = obj[key];
124
+ }
125
+ }
126
+ }
127
+ newObj.default = obj;
128
+ if (cache) {
129
+ cache.set(obj, newObj);
130
+ }
131
+ return newObj;
132
+ }
133
+ function _iterable_to_array_limit(arr, i) {
134
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
135
+ if (_i == null) return;
136
+ var _arr = [];
137
+ var _n = true;
138
+ var _d = false;
139
+ var _s, _e;
140
+ try {
141
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
142
+ _arr.push(_s.value);
143
+ if (i && _arr.length === i) break;
144
+ }
145
+ } catch (err) {
146
+ _d = true;
147
+ _e = err;
148
+ } finally{
149
+ try {
150
+ if (!_n && _i["return"] != null) _i["return"]();
151
+ } finally{
152
+ if (_d) throw _e;
153
+ }
154
+ }
155
+ return _arr;
156
+ }
157
+ function _non_iterable_rest() {
158
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
159
+ }
160
+ function _object_spread(target) {
161
+ for(var i = 1; i < arguments.length; i++){
162
+ var source = arguments[i] != null ? arguments[i] : {};
163
+ var ownKeys = Object.keys(source);
164
+ if (typeof Object.getOwnPropertySymbols === "function") {
165
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
166
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
167
+ }));
168
+ }
169
+ ownKeys.forEach(function(key) {
170
+ _define_property(target, key, source[key]);
171
+ });
172
+ }
173
+ return target;
174
+ }
175
+ function ownKeys(object, enumerableOnly) {
176
+ var keys = Object.keys(object);
177
+ if (Object.getOwnPropertySymbols) {
178
+ var symbols = Object.getOwnPropertySymbols(object);
179
+ if (enumerableOnly) {
180
+ symbols = symbols.filter(function(sym) {
181
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
182
+ });
183
+ }
184
+ keys.push.apply(keys, symbols);
185
+ }
186
+ return keys;
187
+ }
188
+ function _object_spread_props(target, source) {
189
+ source = source != null ? source : {};
190
+ if (Object.getOwnPropertyDescriptors) {
191
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
192
+ } else {
193
+ ownKeys(Object(source)).forEach(function(key) {
194
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
195
+ });
196
+ }
197
+ return target;
198
+ }
199
+ function _sliced_to_array(arr, i) {
200
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
201
+ }
202
+ function _unsupported_iterable_to_array(o, minLen) {
203
+ if (!o) return;
204
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
205
+ var n = Object.prototype.toString.call(o).slice(8, -1);
206
+ if (n === "Object" && o.constructor) n = o.constructor.name;
207
+ if (n === "Map" || n === "Set") return Array.from(n);
208
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
209
+ }
210
+ function _ts_generator(thisArg, body) {
211
+ var f, y, t, _ = {
212
+ label: 0,
213
+ sent: function() {
214
+ if (t[0] & 1) throw t[1];
215
+ return t[1];
216
+ },
217
+ trys: [],
218
+ ops: []
219
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
220
+ return d(g, "next", {
221
+ value: verb(0)
222
+ }), d(g, "throw", {
223
+ value: verb(1)
224
+ }), d(g, "return", {
225
+ value: verb(2)
226
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
227
+ value: function() {
228
+ return this;
229
+ }
230
+ }), g;
231
+ function verb(n) {
232
+ return function(v) {
233
+ return step([
234
+ n,
235
+ v
236
+ ]);
237
+ };
238
+ }
239
+ function step(op) {
240
+ if (f) throw new TypeError("Generator is already executing.");
241
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
242
+ 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;
243
+ if (y = 0, t) op = [
244
+ op[0] & 2,
245
+ t.value
246
+ ];
247
+ switch(op[0]){
248
+ case 0:
249
+ case 1:
250
+ t = op;
251
+ break;
252
+ case 4:
253
+ _.label++;
254
+ return {
255
+ value: op[1],
256
+ done: false
257
+ };
258
+ case 5:
259
+ _.label++;
260
+ y = op[1];
261
+ op = [
262
+ 0
263
+ ];
264
+ continue;
265
+ case 7:
266
+ op = _.ops.pop();
267
+ _.trys.pop();
268
+ continue;
269
+ default:
270
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
271
+ _ = 0;
272
+ continue;
273
+ }
274
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
275
+ _.label = op[1];
276
+ break;
277
+ }
278
+ if (op[0] === 6 && _.label < t[1]) {
279
+ _.label = t[1];
280
+ t = op;
281
+ break;
282
+ }
283
+ if (t && _.label < t[2]) {
284
+ _.label = t[2];
285
+ _.ops.push(op);
286
+ break;
287
+ }
288
+ if (t[2]) _.ops.pop();
289
+ _.trys.pop();
290
+ continue;
291
+ }
292
+ op = body.call(thisArg, _);
293
+ } catch (e) {
294
+ op = [
295
+ 6,
296
+ e
297
+ ];
298
+ y = 0;
299
+ } finally{
300
+ f = t = 0;
301
+ }
302
+ if (op[0] & 5) throw op[1];
303
+ return {
304
+ value: op[0] ? op[1] : void 0,
305
+ done: true
306
+ };
307
+ }
308
+ }
309
+ function createDcrRouter(config) {
310
+ var router = _express.default.Router();
311
+ var store = config.store, issuerUrl = config.issuerUrl, baseUrl = config.baseUrl, scopesSupported = config.scopesSupported, clientConfig = config.clientConfig;
312
+ // Apply required middleware for OAuth 2.0 endpoints (RFC 6749)
313
+ router.use(_express.default.json()); // For /oauth/register (application/json)
314
+ router.use(_express.default.urlencoded({
315
+ extended: true
316
+ })); // For /oauth/token (application/x-www-form-urlencoded)
317
+ /**
318
+ * OAuth Authorization Server Metadata (RFC 8414)
319
+ * GET /.well-known/oauth-authorization-server
320
+ */ router.get('/.well-known/oauth-authorization-server', function(_req, res) {
321
+ var metadata = {
322
+ issuer: issuerUrl,
323
+ authorization_endpoint: "".concat(baseUrl, "/oauth/authorize"),
324
+ token_endpoint: "".concat(baseUrl, "/oauth/token"),
325
+ registration_endpoint: "".concat(baseUrl, "/oauth/register"),
326
+ revocation_endpoint: "".concat(baseUrl, "/oauth/revoke"),
327
+ scopes_supported: scopesSupported,
328
+ response_types_supported: [
329
+ 'code'
330
+ ],
331
+ grant_types_supported: [
332
+ 'authorization_code',
333
+ 'refresh_token'
334
+ ],
335
+ token_endpoint_auth_methods_supported: [
336
+ 'client_secret_basic',
337
+ 'client_secret_post'
338
+ ],
339
+ code_challenge_methods_supported: [
340
+ 'S256',
341
+ 'plain'
342
+ ],
343
+ service_documentation: "".concat(baseUrl, "/docs")
344
+ };
345
+ res.json(metadata);
346
+ });
347
+ /**
348
+ * OAuth Protected Resource Metadata (RFC 9728 - Root)
349
+ * GET /.well-known/oauth-protected-resource
350
+ */ router.get('/.well-known/oauth-protected-resource', function(_req, res) {
351
+ var metadata = {
352
+ resource: baseUrl,
353
+ authorization_servers: [
354
+ baseUrl
355
+ ],
356
+ scopes_supported: scopesSupported,
357
+ bearer_methods_supported: [
358
+ 'header'
359
+ ]
360
+ };
361
+ res.json(metadata);
362
+ });
363
+ /**
364
+ * OAuth Protected Resource Metadata (RFC 9728 - Sub-path /mcp)
365
+ * GET /.well-known/oauth-protected-resource/mcp
366
+ */ router.get('/.well-known/oauth-protected-resource/mcp', function(_req, res) {
367
+ var metadata = {
368
+ resource: "".concat(baseUrl, "/mcp"),
369
+ authorization_servers: [
370
+ baseUrl
371
+ ],
372
+ scopes_supported: scopesSupported,
373
+ bearer_methods_supported: [
374
+ 'header'
375
+ ]
376
+ };
377
+ res.json(metadata);
378
+ });
379
+ /**
380
+ * Dynamic Client Registration (RFC 7591)
381
+ * POST /oauth/register
382
+ */ router.post('/oauth/register', function(req, res) {
383
+ return _async_to_generator(function() {
384
+ var registrationRequest, client, error;
385
+ return _ts_generator(this, function(_state) {
386
+ switch(_state.label){
387
+ case 0:
388
+ _state.trys.push([
389
+ 0,
390
+ 2,
391
+ ,
392
+ 3
393
+ ]);
394
+ registrationRequest = req.body;
395
+ return [
396
+ 4,
397
+ _dcrutilsts.registerClient(store, registrationRequest)
398
+ ];
399
+ case 1:
400
+ client = _state.sent();
401
+ // Return client information (RFC 7591 Section 3.2.1)
402
+ res.status(201).json(client);
403
+ return [
404
+ 3,
405
+ 3
406
+ ];
407
+ case 2:
408
+ error = _state.sent();
409
+ res.status(400).json({
410
+ error: 'invalid_client_metadata',
411
+ error_description: _instanceof(error, Error) ? error.message : 'Invalid registration request'
412
+ });
413
+ return [
414
+ 3,
415
+ 3
416
+ ];
417
+ case 3:
418
+ return [
419
+ 2
420
+ ];
421
+ }
422
+ });
423
+ })();
424
+ });
425
+ /**
426
+ * OAuth Authorization Endpoint (RFC 6749 Section 3.1)
427
+ * GET /oauth/authorize
428
+ *
429
+ * Initiates Microsoft OAuth flow, then generates DCR authorization code
430
+ */ router.get('/oauth/authorize', function(req, res) {
431
+ return _async_to_generator(function() {
432
+ var _req_query, response_type, client_id, redirect_uri, _req_query_scope, scope, _req_query_state, state, code_challenge, code_challenge_method, client, isValidRedirect, msState, dcrRequestState, msAuthUrl;
433
+ return _ts_generator(this, function(_state) {
434
+ switch(_state.label){
435
+ case 0:
436
+ _req_query = req.query, response_type = _req_query.response_type, client_id = _req_query.client_id, redirect_uri = _req_query.redirect_uri, _req_query_scope = _req_query.scope, scope = _req_query_scope === void 0 ? '' : _req_query_scope, _req_query_state = _req_query.state, state = _req_query_state === void 0 ? '' : _req_query_state, code_challenge = _req_query.code_challenge, code_challenge_method = _req_query.code_challenge_method;
437
+ // Validate required parameters
438
+ if (response_type !== 'code') {
439
+ return [
440
+ 2,
441
+ res.status(400).json({
442
+ error: 'unsupported_response_type',
443
+ error_description: 'Only response_type=code is supported'
444
+ })
445
+ ];
446
+ }
447
+ if (!client_id || typeof client_id !== 'string') {
448
+ return [
449
+ 2,
450
+ res.status(400).json({
451
+ error: 'invalid_request',
452
+ error_description: 'client_id is required'
453
+ })
454
+ ];
455
+ }
456
+ if (!redirect_uri || typeof redirect_uri !== 'string') {
457
+ return [
458
+ 2,
459
+ res.status(400).json({
460
+ error: 'invalid_request',
461
+ error_description: 'redirect_uri is required'
462
+ })
463
+ ];
464
+ }
465
+ return [
466
+ 4,
467
+ _dcrutilsts.getClient(store, client_id)
468
+ ];
469
+ case 1:
470
+ client = _state.sent();
471
+ if (!client) {
472
+ return [
473
+ 2,
474
+ res.status(400).json({
475
+ error: 'invalid_client',
476
+ error_description: 'Unknown client_id'
477
+ })
478
+ ];
479
+ }
480
+ return [
481
+ 4,
482
+ _dcrutilsts.validateRedirectUri(store, client_id, redirect_uri)
483
+ ];
484
+ case 2:
485
+ isValidRedirect = _state.sent();
486
+ if (!isValidRedirect) {
487
+ return [
488
+ 2,
489
+ res.status(400).json({
490
+ error: 'invalid_request',
491
+ error_description: 'Invalid redirect_uri'
492
+ })
493
+ ];
494
+ }
495
+ // Store DCR request state for Microsoft OAuth callback
496
+ msState = (0, _crypto.randomUUID)();
497
+ dcrRequestState = {
498
+ client_id: client_id,
499
+ redirect_uri: redirect_uri,
500
+ scope: typeof scope === 'string' ? scope : '',
501
+ state: typeof state === 'string' ? state : undefined,
502
+ code_challenge: typeof code_challenge === 'string' ? code_challenge : undefined,
503
+ code_challenge_method: typeof code_challenge_method === 'string' ? code_challenge_method : undefined,
504
+ created_at: Date.now(),
505
+ expires_at: Date.now() + 600000
506
+ };
507
+ return [
508
+ 4,
509
+ store.set("dcr:ms-state:".concat(msState), dcrRequestState, 600000)
510
+ ];
511
+ case 3:
512
+ _state.sent(); // 10 min TTL
513
+ // Build Microsoft authorization URL
514
+ msAuthUrl = new URL("https://login.microsoftonline.com/".concat(clientConfig.tenantId || 'common', "/oauth2/v2.0/authorize"));
515
+ msAuthUrl.searchParams.set('client_id', clientConfig.clientId);
516
+ msAuthUrl.searchParams.set('response_type', 'code');
517
+ msAuthUrl.searchParams.set('redirect_uri', "".concat(baseUrl, "/oauth/callback"));
518
+ msAuthUrl.searchParams.set('scope', typeof scope === 'string' ? scope : '');
519
+ msAuthUrl.searchParams.set('state', msState);
520
+ msAuthUrl.searchParams.set('response_mode', 'query');
521
+ // Redirect user to Microsoft for authorization
522
+ return [
523
+ 2,
524
+ res.redirect(msAuthUrl.toString())
525
+ ];
526
+ }
527
+ });
528
+ })();
529
+ });
530
+ /**
531
+ * OAuth Callback Handler
532
+ * GET /oauth/callback
533
+ *
534
+ * Handles callback from Microsoft after user authorization
535
+ */ router.get('/oauth/callback', function(req, res) {
536
+ return _async_to_generator(function() {
537
+ var _req_query, msCode, msState, _$error, error_description, dcrRequestState, tokenUrl, tokenParams, tokenResponse, errorData, tokenData, providerTokens, dcrCode, authCode, clientRedirectUrl, error;
538
+ return _ts_generator(this, function(_state) {
539
+ switch(_state.label){
540
+ case 0:
541
+ _req_query = req.query, msCode = _req_query.code, msState = _req_query.state, _$error = _req_query.error, error_description = _req_query.error_description;
542
+ // Handle Microsoft OAuth errors
543
+ if (_$error) {
544
+ return [
545
+ 2,
546
+ res.status(400).json({
547
+ error: _$error,
548
+ error_description: error_description || 'Microsoft OAuth authorization failed'
549
+ })
550
+ ];
551
+ }
552
+ if (!msCode || typeof msCode !== 'string') {
553
+ return [
554
+ 2,
555
+ res.status(400).json({
556
+ error: 'invalid_request',
557
+ error_description: 'Authorization code is required'
558
+ })
559
+ ];
560
+ }
561
+ if (!msState || typeof msState !== 'string') {
562
+ return [
563
+ 2,
564
+ res.status(400).json({
565
+ error: 'invalid_request',
566
+ error_description: 'State parameter is required'
567
+ })
568
+ ];
569
+ }
570
+ return [
571
+ 4,
572
+ store.get("dcr:ms-state:".concat(msState))
573
+ ];
574
+ case 1:
575
+ dcrRequestState = _state.sent();
576
+ if (!dcrRequestState) {
577
+ return [
578
+ 2,
579
+ res.status(400).json({
580
+ error: 'invalid_request',
581
+ error_description: 'Invalid or expired state parameter'
582
+ })
583
+ ];
584
+ }
585
+ // Delete state (one-time use)
586
+ return [
587
+ 4,
588
+ store.delete("dcr:ms-state:".concat(msState))
589
+ ];
590
+ case 2:
591
+ _state.sent();
592
+ _state.label = 3;
593
+ case 3:
594
+ _state.trys.push([
595
+ 3,
596
+ 9,
597
+ ,
598
+ 10
599
+ ]);
600
+ tokenUrl = "https://login.microsoftonline.com/".concat(clientConfig.tenantId || 'common', "/oauth2/v2.0/token");
601
+ tokenParams = new URLSearchParams({
602
+ grant_type: 'authorization_code',
603
+ code: msCode,
604
+ client_id: clientConfig.clientId,
605
+ redirect_uri: "".concat(baseUrl, "/oauth/callback"),
606
+ scope: dcrRequestState.scope
607
+ });
608
+ // Add client_secret if available (confidential client)
609
+ if (clientConfig.clientSecret) {
610
+ tokenParams.set('client_secret', clientConfig.clientSecret);
611
+ }
612
+ return [
613
+ 4,
614
+ fetch(tokenUrl, {
615
+ method: 'POST',
616
+ headers: {
617
+ 'Content-Type': 'application/x-www-form-urlencoded'
618
+ },
619
+ body: tokenParams.toString()
620
+ })
621
+ ];
622
+ case 4:
623
+ tokenResponse = _state.sent();
624
+ if (!!tokenResponse.ok) return [
625
+ 3,
626
+ 6
627
+ ];
628
+ return [
629
+ 4,
630
+ tokenResponse.json()
631
+ ];
632
+ case 5:
633
+ errorData = _state.sent();
634
+ throw new Error("Microsoft token exchange failed: ".concat(errorData.error_description || errorData.error));
635
+ case 6:
636
+ return [
637
+ 4,
638
+ tokenResponse.json()
639
+ ];
640
+ case 7:
641
+ tokenData = _state.sent();
642
+ // Create provider tokens from Microsoft response
643
+ providerTokens = _object_spread_props(_object_spread({
644
+ accessToken: tokenData.access_token
645
+ }, tokenData.refresh_token && {
646
+ refreshToken: tokenData.refresh_token
647
+ }), {
648
+ expiresAt: Date.now() + tokenData.expires_in * 1000,
649
+ scope: tokenData.scope
650
+ });
651
+ // Generate DCR authorization code with real provider tokens
652
+ dcrCode = (0, _crypto.randomUUID)();
653
+ authCode = _object_spread_props(_object_spread({
654
+ code: dcrCode,
655
+ client_id: dcrRequestState.client_id,
656
+ redirect_uri: dcrRequestState.redirect_uri,
657
+ scope: dcrRequestState.scope
658
+ }, dcrRequestState.code_challenge && {
659
+ code_challenge: dcrRequestState.code_challenge
660
+ }, dcrRequestState.code_challenge_method && {
661
+ code_challenge_method: dcrRequestState.code_challenge_method
662
+ }), {
663
+ providerTokens: providerTokens,
664
+ created_at: Date.now(),
665
+ expires_at: Date.now() + 600000
666
+ });
667
+ return [
668
+ 4,
669
+ _dcrutilsts.setAuthCode(store, dcrCode, authCode)
670
+ ];
671
+ case 8:
672
+ _state.sent();
673
+ // Redirect back to MCP client with DCR authorization code
674
+ clientRedirectUrl = new URL(dcrRequestState.redirect_uri);
675
+ clientRedirectUrl.searchParams.set('code', dcrCode);
676
+ if (dcrRequestState.state) {
677
+ clientRedirectUrl.searchParams.set('state', dcrRequestState.state);
678
+ }
679
+ return [
680
+ 2,
681
+ res.redirect(clientRedirectUrl.toString())
682
+ ];
683
+ case 9:
684
+ error = _state.sent();
685
+ return [
686
+ 2,
687
+ res.status(500).json({
688
+ error: 'server_error',
689
+ error_description: _instanceof(error, Error) ? error.message : 'Failed to exchange authorization code'
690
+ })
691
+ ];
692
+ case 10:
693
+ return [
694
+ 2
695
+ ];
696
+ }
697
+ });
698
+ })();
699
+ });
700
+ /**
701
+ * OAuth Token Endpoint (RFC 6749 Section 3.2)
702
+ * POST /oauth/token
703
+ */ router.post('/oauth/token', function(req, res) {
704
+ return _async_to_generator(function() {
705
+ var client_id, client_secret, authHeader, base64Credentials, credentials, _credentials_split, id, secret, _req_body, grant_type, code, redirect_uri, refresh_token, code_verifier, isValidClient, authCode, _authCode_code_challenge_method, method, computedChallenge, accessToken, refreshTokenValue, tokenData, isValidClient1, tokenData1, refreshedProviderTokens, _clientConfig_tenantId, provider, error, newAccessToken, newTokenData;
706
+ return _ts_generator(this, function(_state) {
707
+ switch(_state.label){
708
+ case 0:
709
+ // Extract client credentials from either body or Basic Auth header
710
+ client_id = req.body.client_id;
711
+ client_secret = req.body.client_secret;
712
+ // Support client_secret_basic authentication (RFC 6749 Section 2.3.1)
713
+ authHeader = req.headers.authorization;
714
+ if (authHeader && authHeader.startsWith('Basic ')) {
715
+ base64Credentials = authHeader.substring(6);
716
+ credentials = Buffer.from(base64Credentials, 'base64').toString('utf-8');
717
+ _credentials_split = _sliced_to_array(credentials.split(':'), 2), id = _credentials_split[0], secret = _credentials_split[1];
718
+ client_id = id;
719
+ client_secret = secret;
720
+ }
721
+ _req_body = req.body, grant_type = _req_body.grant_type, code = _req_body.code, redirect_uri = _req_body.redirect_uri, refresh_token = _req_body.refresh_token, code_verifier = _req_body.code_verifier;
722
+ // Validate grant_type
723
+ if (!grant_type) {
724
+ return [
725
+ 2,
726
+ res.status(400).json({
727
+ error: 'invalid_request',
728
+ error_description: 'grant_type is required'
729
+ })
730
+ ];
731
+ }
732
+ if (!(grant_type === 'authorization_code')) return [
733
+ 3,
734
+ 9
735
+ ];
736
+ // Authorization Code Grant
737
+ if (!code || !client_id || !redirect_uri) {
738
+ return [
739
+ 2,
740
+ res.status(400).json({
741
+ error: 'invalid_request',
742
+ error_description: 'code, client_id, and redirect_uri are required'
743
+ })
744
+ ];
745
+ }
746
+ return [
747
+ 4,
748
+ _dcrutilsts.validateClient(store, client_id, client_secret !== null && client_secret !== void 0 ? client_secret : '')
749
+ ];
750
+ case 1:
751
+ isValidClient = _state.sent();
752
+ if (!isValidClient) {
753
+ return [
754
+ 2,
755
+ res.status(401).json({
756
+ error: 'invalid_client',
757
+ error_description: 'Invalid client credentials'
758
+ })
759
+ ];
760
+ }
761
+ return [
762
+ 4,
763
+ _dcrutilsts.getAuthCode(store, code)
764
+ ];
765
+ case 2:
766
+ authCode = _state.sent();
767
+ if (!authCode) {
768
+ return [
769
+ 2,
770
+ res.status(400).json({
771
+ error: 'invalid_grant',
772
+ error_description: 'Invalid or expired authorization code'
773
+ })
774
+ ];
775
+ }
776
+ // Validate authorization code
777
+ if (authCode.client_id !== client_id || authCode.redirect_uri !== redirect_uri) {
778
+ return [
779
+ 2,
780
+ res.status(400).json({
781
+ error: 'invalid_grant',
782
+ error_description: 'Authorization code mismatch'
783
+ })
784
+ ];
785
+ }
786
+ if (!(Date.now() > authCode.expires_at)) return [
787
+ 3,
788
+ 4
789
+ ];
790
+ return [
791
+ 4,
792
+ _dcrutilsts.deleteAuthCode(store, code)
793
+ ];
794
+ case 3:
795
+ _state.sent();
796
+ return [
797
+ 2,
798
+ res.status(400).json({
799
+ error: 'invalid_grant',
800
+ error_description: 'Authorization code expired'
801
+ })
802
+ ];
803
+ case 4:
804
+ // Validate PKCE if used
805
+ if (authCode.code_challenge) {
806
+ ;
807
+ if (!code_verifier) {
808
+ return [
809
+ 2,
810
+ res.status(400).json({
811
+ error: 'invalid_request',
812
+ error_description: 'code_verifier is required for PKCE'
813
+ })
814
+ ];
815
+ }
816
+ // Validate code_verifier against code_challenge
817
+ method = (_authCode_code_challenge_method = authCode.code_challenge_method) !== null && _authCode_code_challenge_method !== void 0 ? _authCode_code_challenge_method : 'plain';
818
+ computedChallenge = method === 'S256' ? (0, _crypto.createHash)('sha256').update(code_verifier).digest('base64url') : code_verifier;
819
+ if (computedChallenge !== authCode.code_challenge) {
820
+ return [
821
+ 2,
822
+ res.status(400).json({
823
+ error: 'invalid_grant',
824
+ error_description: 'Invalid code_verifier'
825
+ })
826
+ ];
827
+ }
828
+ }
829
+ // Delete authorization code (one-time use)
830
+ return [
831
+ 4,
832
+ _dcrutilsts.deleteAuthCode(store, code)
833
+ ];
834
+ case 5:
835
+ _state.sent();
836
+ // Generate DCR access token
837
+ accessToken = (0, _crypto.randomUUID)();
838
+ refreshTokenValue = (0, _crypto.randomUUID)();
839
+ tokenData = {
840
+ access_token: accessToken,
841
+ token_type: 'Bearer',
842
+ expires_in: 3600,
843
+ refresh_token: refreshTokenValue,
844
+ scope: authCode.scope,
845
+ client_id: client_id,
846
+ providerTokens: authCode.providerTokens,
847
+ created_at: Date.now()
848
+ };
849
+ return [
850
+ 4,
851
+ _dcrutilsts.setAccessToken(store, accessToken, tokenData)
852
+ ];
853
+ case 6:
854
+ _state.sent();
855
+ return [
856
+ 4,
857
+ _dcrutilsts.setRefreshToken(store, refreshTokenValue, tokenData)
858
+ ];
859
+ case 7:
860
+ _state.sent();
861
+ // Store provider tokens indexed by DCR access token
862
+ return [
863
+ 4,
864
+ _dcrutilsts.setProviderTokens(store, accessToken, authCode.providerTokens)
865
+ ];
866
+ case 8:
867
+ _state.sent();
868
+ // Return token response
869
+ return [
870
+ 2,
871
+ res.json({
872
+ access_token: tokenData.access_token,
873
+ token_type: tokenData.token_type,
874
+ expires_in: tokenData.expires_in,
875
+ refresh_token: tokenData.refresh_token,
876
+ scope: tokenData.scope
877
+ })
878
+ ];
879
+ case 9:
880
+ if (!(grant_type === 'refresh_token')) return [
881
+ 3,
882
+ 18
883
+ ];
884
+ // Refresh Token Grant
885
+ if (!refresh_token || !client_id) {
886
+ return [
887
+ 2,
888
+ res.status(400).json({
889
+ error: 'invalid_request',
890
+ error_description: 'refresh_token and client_id are required'
891
+ })
892
+ ];
893
+ }
894
+ return [
895
+ 4,
896
+ _dcrutilsts.validateClient(store, client_id, client_secret !== null && client_secret !== void 0 ? client_secret : '')
897
+ ];
898
+ case 10:
899
+ isValidClient1 = _state.sent();
900
+ if (!isValidClient1) {
901
+ return [
902
+ 2,
903
+ res.status(401).json({
904
+ error: 'invalid_client',
905
+ error_description: 'Invalid client credentials'
906
+ })
907
+ ];
908
+ }
909
+ return [
910
+ 4,
911
+ _dcrutilsts.getRefreshToken(store, refresh_token)
912
+ ];
913
+ case 11:
914
+ tokenData1 = _state.sent();
915
+ if (!tokenData1 || tokenData1.client_id !== client_id) {
916
+ return [
917
+ 2,
918
+ res.status(400).json({
919
+ error: 'invalid_grant',
920
+ error_description: 'Invalid refresh token'
921
+ })
922
+ ];
923
+ }
924
+ // Refresh provider tokens if available
925
+ refreshedProviderTokens = tokenData1.providerTokens;
926
+ if (!tokenData1.providerTokens.refreshToken) return [
927
+ 3,
928
+ 15
929
+ ];
930
+ _state.label = 12;
931
+ case 12:
932
+ _state.trys.push([
933
+ 12,
934
+ 14,
935
+ ,
936
+ 15
937
+ ]);
938
+ // Create DcrOAuthProvider instance to refresh Microsoft tokens
939
+ provider = new _dcrts.DcrOAuthProvider(_object_spread_props(_object_spread({
940
+ clientId: clientConfig.clientId
941
+ }, clientConfig.clientSecret && {
942
+ clientSecret: clientConfig.clientSecret
943
+ }), {
944
+ tenantId: (_clientConfig_tenantId = clientConfig.tenantId) !== null && _clientConfig_tenantId !== void 0 ? _clientConfig_tenantId : 'common',
945
+ scope: tokenData1.scope,
946
+ verifyEndpoint: "".concat(baseUrl, "/oauth/verify"),
947
+ logger: {
948
+ info: console.log,
949
+ error: console.error,
950
+ warn: console.warn,
951
+ debug: function() {}
952
+ }
953
+ }));
954
+ return [
955
+ 4,
956
+ provider.refreshAccessToken(tokenData1.providerTokens.refreshToken)
957
+ ];
958
+ case 13:
959
+ // Refresh the Microsoft access token
960
+ refreshedProviderTokens = _state.sent();
961
+ return [
962
+ 3,
963
+ 15
964
+ ];
965
+ case 14:
966
+ error = _state.sent();
967
+ // If refresh fails, continue with existing tokens (they may still be valid)
968
+ console.warn('Provider token refresh failed, using existing tokens:', _instanceof(error, Error) ? error.message : String(error));
969
+ return [
970
+ 3,
971
+ 15
972
+ ];
973
+ case 15:
974
+ // Generate new DCR access token
975
+ newAccessToken = (0, _crypto.randomUUID)();
976
+ newTokenData = _object_spread_props(_object_spread({}, tokenData1), {
977
+ access_token: newAccessToken,
978
+ created_at: Date.now()
979
+ });
980
+ return [
981
+ 4,
982
+ _dcrutilsts.setAccessToken(store, newAccessToken, newTokenData)
983
+ ];
984
+ case 16:
985
+ _state.sent();
986
+ // Store refreshed provider tokens indexed by new DCR access token
987
+ return [
988
+ 4,
989
+ _dcrutilsts.setProviderTokens(store, newAccessToken, refreshedProviderTokens)
990
+ ];
991
+ case 17:
992
+ _state.sent();
993
+ return [
994
+ 2,
995
+ res.json({
996
+ access_token: newTokenData.access_token,
997
+ token_type: newTokenData.token_type,
998
+ expires_in: newTokenData.expires_in,
999
+ scope: newTokenData.scope
1000
+ })
1001
+ ];
1002
+ case 18:
1003
+ return [
1004
+ 2,
1005
+ res.status(400).json({
1006
+ error: 'unsupported_grant_type',
1007
+ error_description: 'Only authorization_code and refresh_token grants are supported'
1008
+ })
1009
+ ];
1010
+ }
1011
+ });
1012
+ })();
1013
+ });
1014
+ /**
1015
+ * OAuth Token Revocation (RFC 7009)
1016
+ * POST /oauth/revoke
1017
+ */ router.post('/oauth/revoke', function(req, res) {
1018
+ return _async_to_generator(function() {
1019
+ var _req_body, token, token_type_hint, client_id, client_secret, isValidClient;
1020
+ return _ts_generator(this, function(_state) {
1021
+ switch(_state.label){
1022
+ case 0:
1023
+ _req_body = req.body, token = _req_body.token, token_type_hint = _req_body.token_type_hint, client_id = _req_body.client_id, client_secret = _req_body.client_secret;
1024
+ if (!token) {
1025
+ return [
1026
+ 2,
1027
+ res.status(400).json({
1028
+ error: 'invalid_request',
1029
+ error_description: 'token is required'
1030
+ })
1031
+ ];
1032
+ }
1033
+ if (!(client_id && client_secret)) return [
1034
+ 3,
1035
+ 2
1036
+ ];
1037
+ return [
1038
+ 4,
1039
+ _dcrutilsts.validateClient(store, client_id, client_secret)
1040
+ ];
1041
+ case 1:
1042
+ isValidClient = _state.sent();
1043
+ if (!isValidClient) {
1044
+ return [
1045
+ 2,
1046
+ res.status(401).json({
1047
+ error: 'invalid_client',
1048
+ error_description: 'Invalid client credentials'
1049
+ })
1050
+ ];
1051
+ }
1052
+ _state.label = 2;
1053
+ case 2:
1054
+ if (!(token_type_hint === 'refresh_token')) return [
1055
+ 3,
1056
+ 4
1057
+ ];
1058
+ return [
1059
+ 4,
1060
+ _dcrutilsts.deleteRefreshToken(store, token)
1061
+ ];
1062
+ case 3:
1063
+ _state.sent();
1064
+ return [
1065
+ 3,
1066
+ 11
1067
+ ];
1068
+ case 4:
1069
+ if (!(token_type_hint === 'access_token')) return [
1070
+ 3,
1071
+ 7
1072
+ ];
1073
+ return [
1074
+ 4,
1075
+ _dcrutilsts.deleteAccessToken(store, token)
1076
+ ];
1077
+ case 5:
1078
+ _state.sent();
1079
+ return [
1080
+ 4,
1081
+ _dcrutilsts.deleteProviderTokens(store, token)
1082
+ ];
1083
+ case 6:
1084
+ _state.sent();
1085
+ return [
1086
+ 3,
1087
+ 11
1088
+ ];
1089
+ case 7:
1090
+ // No hint - try both
1091
+ return [
1092
+ 4,
1093
+ _dcrutilsts.deleteRefreshToken(store, token)
1094
+ ];
1095
+ case 8:
1096
+ _state.sent();
1097
+ return [
1098
+ 4,
1099
+ _dcrutilsts.deleteAccessToken(store, token)
1100
+ ];
1101
+ case 9:
1102
+ _state.sent();
1103
+ return [
1104
+ 4,
1105
+ _dcrutilsts.deleteProviderTokens(store, token)
1106
+ ];
1107
+ case 10:
1108
+ _state.sent();
1109
+ _state.label = 11;
1110
+ case 11:
1111
+ // RFC 7009: Return 200 even if token not found
1112
+ return [
1113
+ 2,
1114
+ res.status(200).send()
1115
+ ];
1116
+ }
1117
+ });
1118
+ })();
1119
+ });
1120
+ /**
1121
+ * Token Verification Endpoint
1122
+ * GET /oauth/verify
1123
+ *
1124
+ * Validates bearer tokens for Resource Server.
1125
+ * Returns AuthInfo with provider tokens for stateless DCR pattern.
1126
+ */ router.get('/oauth/verify', function(req, res) {
1127
+ return _async_to_generator(function() {
1128
+ var authHeader, token, tokenData, now, expiresAt, authInfo;
1129
+ return _ts_generator(this, function(_state) {
1130
+ switch(_state.label){
1131
+ case 0:
1132
+ // Extract bearer token from Authorization header
1133
+ authHeader = req.headers.authorization;
1134
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
1135
+ return [
1136
+ 2,
1137
+ res.status(401).json({
1138
+ error: 'invalid_request',
1139
+ error_description: 'Missing or invalid Authorization header'
1140
+ })
1141
+ ];
1142
+ }
1143
+ token = authHeader.substring(7); // Remove 'Bearer ' prefix
1144
+ return [
1145
+ 4,
1146
+ _dcrutilsts.getAccessToken(store, token)
1147
+ ];
1148
+ case 1:
1149
+ tokenData = _state.sent();
1150
+ if (!tokenData) {
1151
+ return [
1152
+ 2,
1153
+ res.status(401).json({
1154
+ error: 'invalid_token',
1155
+ error_description: 'Unknown or expired access token'
1156
+ })
1157
+ ];
1158
+ }
1159
+ // Check if token is expired
1160
+ now = Date.now();
1161
+ expiresAt = tokenData.created_at + tokenData.expires_in * 1000;
1162
+ if (!(now > expiresAt)) return [
1163
+ 3,
1164
+ 4
1165
+ ];
1166
+ // Remove expired token
1167
+ return [
1168
+ 4,
1169
+ _dcrutilsts.deleteAccessToken(store, token)
1170
+ ];
1171
+ case 2:
1172
+ _state.sent();
1173
+ return [
1174
+ 4,
1175
+ _dcrutilsts.deleteProviderTokens(store, token)
1176
+ ];
1177
+ case 3:
1178
+ _state.sent();
1179
+ return [
1180
+ 2,
1181
+ res.status(401).json({
1182
+ error: 'invalid_token',
1183
+ error_description: 'Access token has expired'
1184
+ })
1185
+ ];
1186
+ case 4:
1187
+ // Return AuthInfo with provider tokens for stateless DCR
1188
+ authInfo = {
1189
+ token: token,
1190
+ clientId: tokenData.client_id,
1191
+ scopes: tokenData.scope ? tokenData.scope.split(' ') : [],
1192
+ expiresAt: expiresAt,
1193
+ providerTokens: tokenData.providerTokens
1194
+ };
1195
+ return [
1196
+ 2,
1197
+ res.json(authInfo)
1198
+ ];
1199
+ }
1200
+ });
1201
+ })();
1202
+ });
1203
+ /**
1204
+ * Debug endpoint to list registered clients (development only)
1205
+ */ router.get('/debug/clients', function(_req, res) {
1206
+ return _async_to_generator(function() {
1207
+ var clients;
1208
+ return _ts_generator(this, function(_state) {
1209
+ switch(_state.label){
1210
+ case 0:
1211
+ return [
1212
+ 4,
1213
+ _dcrutilsts.listClients(store)
1214
+ ];
1215
+ case 1:
1216
+ clients = _state.sent();
1217
+ res.json(clients);
1218
+ return [
1219
+ 2
1220
+ ];
1221
+ }
1222
+ });
1223
+ })();
1224
+ });
1225
+ return router;
1226
+ }
1227
+ /* 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; }