@softure-ai/mcp-access 0.1.6 → 0.1.8

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 (148) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +146 -21
  3. package/adoption/move-app-tables.sql +100 -0
  4. package/dist/contract.d.ts +13 -1
  5. package/dist/contract.d.ts.map +1 -1
  6. package/dist/index.d.ts +58 -3
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +26 -5
  9. package/dist/index.js.map +1 -1
  10. package/dist/messages/en.d.ts +28 -0
  11. package/dist/messages/en.d.ts.map +1 -1
  12. package/dist/messages/en.js +28 -0
  13. package/dist/messages/en.js.map +1 -1
  14. package/dist/messages/index.d.ts +56 -0
  15. package/dist/messages/index.d.ts.map +1 -1
  16. package/dist/messages/pl.d.ts.map +1 -1
  17. package/dist/messages/pl.js +28 -0
  18. package/dist/messages/pl.js.map +1 -1
  19. package/dist/next/actions.d.ts +3 -1
  20. package/dist/next/actions.d.ts.map +1 -1
  21. package/dist/next/actions.js +23 -2
  22. package/dist/next/actions.js.map +1 -1
  23. package/dist/next/context.d.ts +7 -1
  24. package/dist/next/context.d.ts.map +1 -1
  25. package/dist/next/context.js +12 -10
  26. package/dist/next/context.js.map +1 -1
  27. package/dist/next/index.d.ts +4 -1
  28. package/dist/next/index.d.ts.map +1 -1
  29. package/dist/next/index.js +5 -2
  30. package/dist/next/index.js.map +1 -1
  31. package/dist/next/oauth-page.d.ts +7 -0
  32. package/dist/next/oauth-page.d.ts.map +1 -0
  33. package/dist/next/oauth-page.js +36 -0
  34. package/dist/next/oauth-page.js.map +1 -0
  35. package/dist/next/oauth-routes.d.ts +19 -0
  36. package/dist/next/oauth-routes.d.ts.map +1 -0
  37. package/dist/next/oauth-routes.js +53 -0
  38. package/dist/next/oauth-routes.js.map +1 -0
  39. package/dist/next/pages.d.ts.map +1 -1
  40. package/dist/next/pages.js +13 -2
  41. package/dist/next/pages.js.map +1 -1
  42. package/dist/options.d.ts +40 -0
  43. package/dist/options.d.ts.map +1 -1
  44. package/dist/options.js +94 -1
  45. package/dist/options.js.map +1 -1
  46. package/dist/origins.d.ts +27 -0
  47. package/dist/origins.d.ts.map +1 -0
  48. package/dist/origins.js +32 -0
  49. package/dist/origins.js.map +1 -0
  50. package/dist/schema.d.ts +486 -0
  51. package/dist/schema.d.ts.map +1 -1
  52. package/dist/schema.js +45 -3
  53. package/dist/schema.js.map +1 -1
  54. package/dist/server/context.d.ts +4 -0
  55. package/dist/server/context.d.ts.map +1 -0
  56. package/dist/server/context.js +13 -0
  57. package/dist/server/context.js.map +1 -0
  58. package/dist/server/endpoint.d.ts +2 -4
  59. package/dist/server/endpoint.d.ts.map +1 -1
  60. package/dist/server/endpoint.js +14 -9
  61. package/dist/server/endpoint.js.map +1 -1
  62. package/dist/server/health.d.ts.map +1 -1
  63. package/dist/server/health.js +5 -3
  64. package/dist/server/health.js.map +1 -1
  65. package/dist/server/index.d.ts +8 -0
  66. package/dist/server/index.d.ts.map +1 -1
  67. package/dist/server/index.js +7 -0
  68. package/dist/server/index.js.map +1 -1
  69. package/dist/server/oauth-http.d.ts +127 -0
  70. package/dist/server/oauth-http.d.ts.map +1 -0
  71. package/dist/server/oauth-http.js +397 -0
  72. package/dist/server/oauth-http.js.map +1 -0
  73. package/dist/server/oauth-validation.d.ts +28 -0
  74. package/dist/server/oauth-validation.d.ts.map +1 -0
  75. package/dist/server/oauth-validation.js +88 -0
  76. package/dist/server/oauth-validation.js.map +1 -0
  77. package/dist/server/oauth.d.ts +106 -0
  78. package/dist/server/oauth.d.ts.map +1 -0
  79. package/dist/server/oauth.js +235 -0
  80. package/dist/server/oauth.js.map +1 -0
  81. package/dist/server/options.d.ts +11 -2
  82. package/dist/server/options.d.ts.map +1 -1
  83. package/dist/server/options.js +11 -4
  84. package/dist/server/options.js.map +1 -1
  85. package/dist/server/origins.d.ts +8 -0
  86. package/dist/server/origins.d.ts.map +1 -0
  87. package/dist/server/origins.js +15 -0
  88. package/dist/server/origins.js.map +1 -0
  89. package/dist/server/pkce.d.ts +7 -0
  90. package/dist/server/pkce.d.ts.map +1 -0
  91. package/dist/server/pkce.js +24 -0
  92. package/dist/server/pkce.js.map +1 -0
  93. package/dist/server/privacy.d.ts +7 -0
  94. package/dist/server/privacy.d.ts.map +1 -1
  95. package/dist/server/privacy.js +19 -9
  96. package/dist/server/privacy.js.map +1 -1
  97. package/dist/server/scopes.d.ts +5 -0
  98. package/dist/server/scopes.d.ts.map +1 -0
  99. package/dist/server/scopes.js +6 -0
  100. package/dist/server/scopes.js.map +1 -0
  101. package/dist/server/tokens.d.ts +18 -6
  102. package/dist/server/tokens.d.ts.map +1 -1
  103. package/dist/server/tokens.js +60 -25
  104. package/dist/server/tokens.js.map +1 -1
  105. package/dist/ui/consent-form.d.ts +31 -0
  106. package/dist/ui/consent-form.d.ts.map +1 -0
  107. package/dist/ui/consent-form.js +24 -0
  108. package/dist/ui/consent-form.js.map +1 -0
  109. package/dist/ui/index.d.ts +2 -1
  110. package/dist/ui/index.d.ts.map +1 -1
  111. package/dist/ui/index.js +1 -0
  112. package/dist/ui/index.js.map +1 -1
  113. package/dist/ui/token-manager.d.ts +16 -2
  114. package/dist/ui/token-manager.d.ts.map +1 -1
  115. package/dist/ui/token-manager.js +6 -2
  116. package/dist/ui/token-manager.js.map +1 -1
  117. package/migrations/0002_create_oauth_grants.sql +68 -0
  118. package/module.json +18 -4
  119. package/package.json +2 -1
  120. package/src/contract.ts +16 -1
  121. package/src/index.ts +33 -4
  122. package/src/messages/en.ts +28 -0
  123. package/src/messages/pl.ts +28 -0
  124. package/src/next/actions.ts +23 -3
  125. package/src/next/context.ts +15 -8
  126. package/src/next/index.ts +12 -2
  127. package/src/next/oauth-page.tsx +68 -0
  128. package/src/next/oauth-routes.ts +73 -0
  129. package/src/next/pages.tsx +16 -3
  130. package/src/options.ts +107 -1
  131. package/src/origins.ts +48 -0
  132. package/src/schema.ts +51 -3
  133. package/src/server/context.ts +14 -0
  134. package/src/server/endpoint.ts +14 -9
  135. package/src/server/health.ts +5 -3
  136. package/src/server/index.ts +56 -0
  137. package/src/server/oauth-http.ts +480 -0
  138. package/src/server/oauth-validation.ts +106 -0
  139. package/src/server/oauth.ts +315 -0
  140. package/src/server/options.ts +20 -4
  141. package/src/server/origins.ts +19 -0
  142. package/src/server/pkce.ts +27 -0
  143. package/src/server/privacy.ts +26 -9
  144. package/src/server/scopes.ts +6 -0
  145. package/src/server/tokens.ts +62 -25
  146. package/src/ui/consent-form.tsx +103 -0
  147. package/src/ui/index.ts +3 -0
  148. package/src/ui/token-manager.tsx +79 -3
@@ -58,12 +58,40 @@ export declare const en: {
58
58
  revoke: string;
59
59
  revoking: string;
60
60
  };
61
+ grants: {
62
+ title: string;
63
+ lead: string;
64
+ empty: string;
65
+ connectedOn: string;
66
+ disconnect: string;
67
+ disconnecting: string;
68
+ };
69
+ consent: {
70
+ title: string;
71
+ lead: string;
72
+ app: string;
73
+ returnsTo: string;
74
+ account: string;
75
+ access: string;
76
+ readAccess: string;
77
+ allowWrite: string;
78
+ allowWriteHint: string;
79
+ allow: string;
80
+ deny: string;
81
+ errorTitle: string;
82
+ unknownClient: string;
83
+ redirectMismatch: string;
84
+ invalidRequest: string;
85
+ nothingGranted: string;
86
+ backToApp: string;
87
+ };
61
88
  errors: {
62
89
  "mcp-access": {
63
90
  name_required: string;
64
91
  name_too_long: string;
65
92
  token_limit_reached: string;
66
93
  token_not_found: string;
94
+ grant_not_found: string;
67
95
  };
68
96
  auth: {
69
97
  unauthenticated: string;
@@ -1 +1 @@
1
- {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2Ed,CAAC"}
1
+ {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuGd,CAAC"}
@@ -58,12 +58,40 @@ export const en = {
58
58
  revoke: "Revoke",
59
59
  revoking: "Revoking…",
60
60
  },
61
+ grants: {
62
+ title: "Connected apps",
63
+ lead: "Assistants you connected by signing in, such as claude.ai or ChatGPT. Disconnecting one stops its access at once.",
64
+ empty: "No app is connected.",
65
+ connectedOn: "Connected {date}",
66
+ disconnect: "Disconnect",
67
+ disconnecting: "Disconnecting…",
68
+ },
69
+ consent: {
70
+ title: "{client} wants access to your account",
71
+ lead: "The assistant can answer questions with your data in this app. You can disconnect it at any time on the AI assistant access page.",
72
+ app: "App",
73
+ returnsTo: "returns to {target}",
74
+ account: "Account",
75
+ access: "Access",
76
+ readAccess: "Read your data",
77
+ allowWrite: "Also allow changes",
78
+ allowWriteHint: "Without it, the assistant can only read.",
79
+ allow: "Allow",
80
+ deny: "Deny",
81
+ errorTitle: "The assistant cannot be connected",
82
+ unknownClient: "The app that sent you here is not registered. Connect it again from the assistant.",
83
+ redirectMismatch: "The return address does not match the one the app registered. Connect it again from the assistant.",
84
+ invalidRequest: "The app sent a connection request this app cannot accept.",
85
+ nothingGranted: "No access was granted.",
86
+ backToApp: "Back to the app ({target})",
87
+ },
61
88
  errors: {
62
89
  "mcp-access": {
63
90
  name_required: "Give the token a name, so you can tell it from the others.",
64
91
  name_too_long: "The name is too long.",
65
92
  token_limit_reached: "You already hold the most active tokens allowed. Revoke one before creating another.",
66
93
  token_not_found: "This token no longer exists. It may have been revoked already.",
94
+ grant_not_found: "This app is no longer connected.",
67
95
  },
68
96
  auth: {
69
97
  unauthenticated: "Your session has ended. Log in again.",
@@ -1 +1 @@
1
- {"version":3,"file":"en.js","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,IAAI,EAAE;QACJ,KAAK,EAAE,qBAAqB;QAC5B,IAAI,EAAE,uIAAuI;KAC9I;IACD,KAAK,EAAE;QACL,KAAK,EAAE,0BAA0B;QACjC,KAAK,EAAE,6BAA6B;QACpC,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,cAAc;QACrB,gBAAgB,EAAE,uCAAuC;KAC1D;IACD,KAAK,EAAE;QACL,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,uDAAuD;QACjE,QAAQ,EAAE,eAAe;QACzB,YAAY,EAAE,0CAA0C;QACxD,MAAM,EAAE,cAAc;QACtB,OAAO,EAAE,WAAW;QACpB,KAAK,EAAE,yCAAyC;KACjD;IACD,MAAM,EAAE;QACN,KAAK,EAAE,uBAAuB;QAC9B,IAAI,EAAE,uFAAuF;QAC7F,OAAO,EAAE,qBAAqB;QAC9B,QAAQ,EAAE,2BAA2B;QACrC,SAAS,EAAE,sCAAsC;QACjD,WAAW,EAAE,oCAAoC;QACjD,UAAU,EAAE,iGAAiG;QAC7G,cAAc,EAAE,qBAAqB;QACrC,YAAY,EAAE,gCAAgC;QAC9C,SAAS,EAAE,gDAAgD;QAC3D,YAAY,EAAE,6CAA6C;QAC3D,WAAW,EAAE,wDAAwD;QACrE,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,sBAAsB;KAC7B;IACD,KAAK,EAAE;QACL,eAAe,EAAE,6IAA6I;KAC/J;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,aAAa;QACpB,KAAK,EAAE,yBAAyB;QAChC,QAAQ,EAAE,WAAW;QACrB,SAAS,EAAE,iBAAiB;QAC5B,MAAM,EAAE,QAAQ;QAChB,OAAO,EAAE,SAAS;QAClB,YAAY,EAAE,eAAe;QAC7B,eAAe,EAAE,kBAAkB;QACnC,aAAa,EAAE,wBAAwB;QACvC,SAAS,EAAE,oBAAoB;QAC/B,SAAS,EAAE,mBAAmB;QAC9B,SAAS,EAAE,gBAAgB;QAC3B,QAAQ,EAAE,kBAAkB;QAC5B,SAAS,EAAE,cAAc;QACzB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,WAAW;KACtB;IACD,MAAM,EAAE;QACN,YAAY,EAAE;YACZ,aAAa,EAAE,4DAA4D;YAC3E,aAAa,EAAE,uBAAuB;YACtC,mBAAmB,EAAE,sFAAsF;YAC3G,eAAe,EAAE,gEAAgE;SAClF;QACD,IAAI,EAAE;YACJ,eAAe,EAAE,uCAAuC;SACzD;QACD,IAAI,EAAE;YACJ,eAAe,EAAE,0DAA0D;YAC3E,UAAU,EAAE,0DAA0D;SACvE;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"en.js","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"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"}
@@ -62,12 +62,40 @@ export declare const mcpAccessMessages: {
62
62
  revoke: string;
63
63
  revoking: string;
64
64
  };
65
+ grants: {
66
+ title: string;
67
+ lead: string;
68
+ empty: string;
69
+ connectedOn: string;
70
+ disconnect: string;
71
+ disconnecting: string;
72
+ };
73
+ consent: {
74
+ title: string;
75
+ lead: string;
76
+ app: string;
77
+ returnsTo: string;
78
+ account: string;
79
+ access: string;
80
+ readAccess: string;
81
+ allowWrite: string;
82
+ allowWriteHint: string;
83
+ allow: string;
84
+ deny: string;
85
+ errorTitle: string;
86
+ unknownClient: string;
87
+ redirectMismatch: string;
88
+ invalidRequest: string;
89
+ nothingGranted: string;
90
+ backToApp: string;
91
+ };
65
92
  errors: {
66
93
  "mcp-access": {
67
94
  name_required: string;
68
95
  name_too_long: string;
69
96
  token_limit_reached: string;
70
97
  token_not_found: string;
98
+ grant_not_found: string;
71
99
  };
72
100
  auth: {
73
101
  unauthenticated: string;
@@ -138,12 +166,40 @@ export declare const mcpAccessMessages: {
138
166
  revoke: string;
139
167
  revoking: string;
140
168
  };
169
+ grants: {
170
+ title: string;
171
+ lead: string;
172
+ empty: string;
173
+ connectedOn: string;
174
+ disconnect: string;
175
+ disconnecting: string;
176
+ };
177
+ consent: {
178
+ title: string;
179
+ lead: string;
180
+ app: string;
181
+ returnsTo: string;
182
+ account: string;
183
+ access: string;
184
+ readAccess: string;
185
+ allowWrite: string;
186
+ allowWriteHint: string;
187
+ allow: string;
188
+ deny: string;
189
+ errorTitle: string;
190
+ unknownClient: string;
191
+ redirectMismatch: string;
192
+ invalidRequest: string;
193
+ nothingGranted: string;
194
+ backToApp: string;
195
+ };
141
196
  errors: {
142
197
  "mcp-access": {
143
198
  name_required: string;
144
199
  name_too_long: string;
145
200
  token_limit_reached: string;
146
201
  token_not_found: string;
202
+ grant_not_found: string;
147
203
  };
148
204
  auth: {
149
205
  unauthenticated: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAG7B,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAa,CAAC;AAE5C,MAAM,MAAM,iBAAiB,GAAG,OAAO,EAAE,CAAC;AAE1C,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAOlG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAG7B,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAa,CAAC;AAE5C,MAAM,MAAM,iBAAiB,GAAG,OAAO,EAAE,CAAC;AAE1C,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAOlG"}
@@ -1 +1 @@
1
- {"version":3,"file":"pl.d.ts","sourceRoot":"","sources":["../../src/messages/pl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAElC,eAAO,MAAM,EAAE,EAAE,OAAO,EA2EvB,CAAC"}
1
+ {"version":3,"file":"pl.d.ts","sourceRoot":"","sources":["../../src/messages/pl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAElC,eAAO,MAAM,EAAE,EAAE,OAAO,EAuGvB,CAAC"}
@@ -58,12 +58,40 @@ export const pl = {
58
58
  revoke: "Unieważnij",
59
59
  revoking: "Unieważnianie…",
60
60
  },
61
+ grants: {
62
+ title: "Połączone aplikacje",
63
+ lead: "Asystenci połączeni przez logowanie, na przykład claude.ai albo ChatGPT. Odłączenie od razu odbiera im dostęp.",
64
+ empty: "Żadna aplikacja nie jest połączona.",
65
+ connectedOn: "Połączono {date}",
66
+ disconnect: "Odłącz",
67
+ disconnecting: "Odłączanie…",
68
+ },
69
+ consent: {
70
+ title: "{client} prosi o dostęp do Twojego konta",
71
+ lead: "Asystent odpowie na pytania, korzystając z Twoich danych w tej aplikacji. Możesz go odłączyć w każdej chwili na stronie dostępu dla asystenta AI.",
72
+ app: "Aplikacja",
73
+ returnsTo: "wróci na {target}",
74
+ account: "Konto",
75
+ access: "Dostęp",
76
+ readAccess: "Odczyt Twoich danych",
77
+ allowWrite: "Pozwól też na zmiany",
78
+ allowWriteHint: "Bez tego asystent może tylko czytać.",
79
+ allow: "Zezwól",
80
+ deny: "Odmów",
81
+ errorTitle: "Nie da się połączyć asystenta",
82
+ unknownClient: "Aplikacja, która Cię tu przysłała, nie jest zarejestrowana. Połącz ją od nowa z poziomu asystenta.",
83
+ redirectMismatch: "Adres powrotu nie zgadza się z tym, który aplikacja zarejestrowała. Połącz ją od nowa z poziomu asystenta.",
84
+ invalidRequest: "Aplikacja wysłała żądanie połączenia, którego ta aplikacja nie może przyjąć.",
85
+ nothingGranted: "Nie nadano żadnego dostępu.",
86
+ backToApp: "Wróć do aplikacji ({target})",
87
+ },
61
88
  errors: {
62
89
  "mcp-access": {
63
90
  name_required: "Nadaj tokenowi nazwę, żeby odróżnić go od pozostałych.",
64
91
  name_too_long: "Nazwa jest za długa.",
65
92
  token_limit_reached: "Masz już najwięcej aktywnych tokenów, ile można. Unieważnij któryś, zanim utworzysz nowy.",
66
93
  token_not_found: "Ten token już nie istnieje. Mógł zostać unieważniony.",
94
+ grant_not_found: "Ta aplikacja nie jest już połączona.",
67
95
  },
68
96
  auth: {
69
97
  unauthenticated: "Twoja sesja wygasła. Zaloguj się ponownie.",
@@ -1 +1 @@
1
- {"version":3,"file":"pl.js","sourceRoot":"","sources":["../../src/messages/pl.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,EAAE,GAAc;IAC3B,IAAI,EAAE;QACJ,KAAK,EAAE,yBAAyB;QAChC,IAAI,EAAE,mJAAmJ;KAC1J;IACD,KAAK,EAAE;QACL,KAAK,EAAE,kBAAkB;QACzB,KAAK,EAAE,oDAAoD;QAC3D,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,cAAc;QACrB,gBAAgB,EAAE,0CAA0C;KAC7D;IACD,KAAK,EAAE;QACL,KAAK,EAAE,YAAY;QACnB,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,2DAA2D;QACrE,QAAQ,EAAE,kBAAkB;QAC5B,YAAY,EAAE,sCAAsC;QACpD,MAAM,EAAE,cAAc;QACtB,OAAO,EAAE,YAAY;QACrB,KAAK,EAAE,+CAA+C;KACvD;IACD,MAAM,EAAE;QACN,KAAK,EAAE,yBAAyB;QAChC,IAAI,EAAE,+FAA+F;QACrG,OAAO,EAAE,mBAAmB;QAC5B,QAAQ,EAAE,8BAA8B;QACxC,SAAS,EAAE,wCAAwC;QACnD,WAAW,EAAE,oDAAoD;QACjE,UAAU,EAAE,4EAA4E;QACxF,cAAc,EAAE,sBAAsB;QACtC,YAAY,EAAE,qCAAqC;QACnD,SAAS,EAAE,iDAAiD;QAC5D,YAAY,EAAE,6CAA6C;QAC3D,WAAW,EAAE,sDAAsD;QACnE,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,YAAY;QACpB,IAAI,EAAE,qBAAqB;KAC5B;IACD,KAAK,EAAE;QACL,eAAe,EAAE,kJAAkJ;KACpK;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,cAAc;QACrB,KAAK,EAAE,mCAAmC;QAC1C,QAAQ,EAAE,cAAc;QACxB,SAAS,EAAE,iBAAiB;QAC5B,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,QAAQ;QACjB,YAAY,EAAE,aAAa;QAC3B,eAAe,EAAE,cAAc;QAC/B,aAAa,EAAE,sBAAsB;QACrC,SAAS,EAAE,iBAAiB;QAC5B,SAAS,EAAE,eAAe;QAC1B,SAAS,EAAE,kBAAkB;QAC7B,QAAQ,EAAE,uBAAuB;QACjC,SAAS,EAAE,oBAAoB;QAC/B,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,gBAAgB;KAC3B;IACD,MAAM,EAAE;QACN,YAAY,EAAE;YACZ,aAAa,EAAE,wDAAwD;YACvE,aAAa,EAAE,sBAAsB;YACrC,mBAAmB,EAAE,2FAA2F;YAChH,eAAe,EAAE,uDAAuD;SACzE;QACD,IAAI,EAAE;YACJ,eAAe,EAAE,4CAA4C;SAC9D;QACD,IAAI,EAAE;YACJ,eAAe,EAAE,mEAAmE;YACpF,UAAU,EAAE,mEAAmE;SAChF;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"pl.js","sourceRoot":"","sources":["../../src/messages/pl.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
- import type { IssueTokenFormState, RevokeTokenFormState } from "../contract.js";
1
+ import type { IssueTokenFormState, RevokeGrantFormState, RevokeTokenFormState } from "../contract.js";
2
2
  /** Issues a token for the signed-in user and returns its plaintext with the setup snippets, once. */
3
3
  export declare function issueTokenAction(_previous: IssueTokenFormState, formData: FormData): Promise<IssueTokenFormState>;
4
4
  /** Revokes one of the signed-in user's tokens; another account's id matches nothing. */
5
5
  export declare function revokeTokenAction(_previous: RevokeTokenFormState, formData: FormData): Promise<RevokeTokenFormState>;
6
+ /** Disconnects one of the signed-in user's OAuth apps: the grant and its access tokens go at once. */
7
+ export declare function revokeGrantAction(_previous: RevokeGrantFormState, formData: FormData): Promise<RevokeGrantFormState>;
6
8
  //# sourceMappingURL=actions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/next/actions.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AA8BhF,qGAAqG;AACrG,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA+BvH;AAED,wFAAwF;AACxF,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAc1H"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/next/actions.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AA+BtG,qGAAqG;AACrG,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAiCvH;AAED,wFAAwF;AACxF,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAc1H;AAED,sGAAsG;AACtG,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAc1H"}
@@ -10,8 +10,9 @@ import { z } from "zod";
10
10
  import { getMcpClientSetup } from "../client-setup.js";
11
11
  import { MAX_TOKEN_NAME_LENGTH } from "../options.js";
12
12
  import { getMcpAccessMessages, getMcpAccessOptions, getMcpAccessRoutes, getMcpEndpointUrl } from "../server/options.js";
13
+ import { revokeOAuthGrant } from "../server/oauth.js";
13
14
  import { issueAccessToken, revokeAccessToken } from "../server/tokens.js";
14
- import { getMcpAccessContext } from "./context.js";
15
+ import { getMcpAccessContext, getRequestOrigins } from "./context.js";
15
16
  import { formatDate } from "./format.js";
16
17
  /** Longer values are cut: the server functions refuse them anyway, and nothing huge is echoed back. */
17
18
  const MAX_FIELD_LENGTH = MAX_TOKEN_NAME_LENGTH * 4;
@@ -41,6 +42,8 @@ export async function issueTokenAction(_previous, formData) {
41
42
  // Every field has a `catch`, so parsing cannot fail.
42
43
  const input = issueInput.parse({ name: formData.get("name"), canWrite: formData.get("canWrite") });
43
44
  try {
45
+ // Resolved before issuing: a failure afterwards would leave a token nobody received.
46
+ const endpointUrl = getMcpEndpointUrl(config, await getRequestOrigins(config, getMcpAccessRoutes(config).page));
44
47
  const result = await issueAccessToken(await getMcpAccessContext(config), { userId: user.id, name: input.name, canWrite: input.canWrite !== null });
45
48
  if (!result.ok)
46
49
  return { status: "error", error: result.error };
@@ -56,7 +59,7 @@ export async function issueTokenAction(_previous, formData) {
56
59
  expiresText: formatMessage(messages.issued.expires, { date: formatDate(config, issued.expiresAt) }),
57
60
  setup: getMcpClientSetup({
58
61
  serverName: getMcpAccessOptions(config).serverName,
59
- endpointUrl: getMcpEndpointUrl(config),
62
+ endpointUrl,
60
63
  token: issued.token,
61
64
  promptTemplate: messages.setup.assistantPrompt,
62
65
  }),
@@ -85,4 +88,22 @@ export async function revokeTokenAction(_previous, formData) {
85
88
  return { status: "error", error: reportFailure("revoking a token", error) };
86
89
  }
87
90
  }
91
+ /** Disconnects one of the signed-in user's OAuth apps: the grant and its access tokens go at once. */
92
+ export async function revokeGrantAction(_previous, formData) {
93
+ const config = getSoftureConfig();
94
+ const user = await getCurrentUser();
95
+ if (user === null)
96
+ return { status: "error", error: "auth.unauthenticated" };
97
+ const input = revokeInput.parse({ id: formData.get("id") });
98
+ try {
99
+ const result = await revokeOAuthGrant(await getMcpAccessContext(config), { userId: user.id, grantId: input.id });
100
+ if (!result.ok)
101
+ return { status: "error", error: result.error };
102
+ refreshPage(config);
103
+ return { status: "ok" };
104
+ }
105
+ catch (error) {
106
+ return { status: "error", error: reportFailure("disconnecting an app", error) };
107
+ }
108
+ }
88
109
  //# sourceMappingURL=actions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/next/actions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/next/actions.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,10 @@
1
- import { type SoftureConfig } from "@softure-ai/core";
1
+ import type { SoftureConfig } from "@softure-ai/core";
2
+ import type { McpOrigins } from "../origins.js";
2
3
  import type { McpAccessContext } from "../server/tokens.js";
3
4
  export declare function getMcpAccessContext(config?: SoftureConfig): Promise<McpAccessContext>;
5
+ /**
6
+ * The origins of the request a page or a server action runs in, from Next's `headers()`: the same
7
+ * ones the route handlers resolve, so the consent page and its decision agree.
8
+ */
9
+ export declare function getRequestOrigins(config: SoftureConfig, path: string): Promise<McpOrigins>;
4
10
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/next/context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,wBAAsB,mBAAmB,CAAC,MAAM,GAAE,aAAkC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAM/G"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/next/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,aAAkC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAEzG;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAGhG"}
@@ -1,13 +1,15 @@
1
- // What the adapter hands the server functions: the registered config, the process-wide database
2
- // handle and the wall clock.
3
- import { systemClock } from "@softure-ai/core";
4
1
  import { getSoftureConfig } from "@softure-ai/core/next";
5
- import { getConfiguredDatabase } from "@softure-ai/db";
6
- export async function getMcpAccessContext(config = getSoftureConfig()) {
7
- if (config.database === null) {
8
- throw new Error("@softure-ai/mcp-access: softure.config.ts has no database; mcp-access needs one");
9
- }
10
- const { db } = await getConfiguredDatabase(config.database);
11
- return { db, clock: systemClock, config };
2
+ import { createMcpAccessContext } from "../server/context.js";
3
+ import { resolveMcpOrigins } from "../server/origins.js";
4
+ export function getMcpAccessContext(config = getSoftureConfig()) {
5
+ return createMcpAccessContext(config);
6
+ }
7
+ /**
8
+ * The origins of the request a page or a server action runs in, from Next's `headers()`: the same
9
+ * ones the route handlers resolve, so the consent page and its decision agree.
10
+ */
11
+ export async function getRequestOrigins(config, path) {
12
+ const { headers } = await import("next/headers");
13
+ return resolveMcpOrigins(config, { url: new URL(path, config.appOrigin).toString(), headers: await headers() });
12
14
  }
13
15
  //# sourceMappingURL=context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/next/context.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,6BAA6B;AAC7B,OAAO,EAAE,WAAW,EAAsB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,SAAwB,gBAAgB,EAAE;IAClF,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACrG,CAAC;IACD,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,qBAAqB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/next/context.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,MAAM,UAAU,mBAAmB,CAAC,SAAwB,gBAAgB,EAAE;IAC5E,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAqB,EAAE,IAAY;IACzE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;IACjD,OAAO,iBAAiB,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,EAAE,EAAE,CAAC,CAAC;AAClH,CAAC"}
@@ -1,4 +1,7 @@
1
- export { issueTokenAction, revokeTokenAction } from "./actions.js";
1
+ export { issueTokenAction, revokeGrantAction, revokeTokenAction } from "./actions.js";
2
+ export { OAuthConsentPage, type OAuthConsentPageProps } from "./oauth-page.js";
3
+ export { answerOAuthPreflight, decideOAuthAuthorizationRoute, exchangeOAuthTokenRoute, getAuthorizationServerMetadataRoute, getProtectedResourceMetadataRoute, registerOAuthClientRoute, } from "./oauth-routes.js";
4
+ export { getMcpAccessContext } from "./context.js";
2
5
  export { McpAccessPage } from "./pages.js";
3
6
  export { createMcpRoute } from "./route.js";
4
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EACL,oBAAoB,EACpB,6BAA6B,EAC7B,uBAAuB,EACvB,mCAAmC,EACnC,iCAAiC,EACjC,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -1,6 +1,9 @@
1
1
  // The Next.js adapter of @softure-ai/mcp-access: the MCP route factory, the token page and its
2
- // server actions (docs/02-module-standard.md §8).
3
- export { issueTokenAction, revokeTokenAction } from "./actions.js";
2
+ // server actions, and the OAuth routes and consent page (docs/02-module-standard.md §8).
3
+ export { issueTokenAction, revokeGrantAction, revokeTokenAction } from "./actions.js";
4
+ export { OAuthConsentPage } from "./oauth-page.js";
5
+ export { answerOAuthPreflight, decideOAuthAuthorizationRoute, exchangeOAuthTokenRoute, getAuthorizationServerMetadataRoute, getProtectedResourceMetadataRoute, registerOAuthClientRoute, } from "./oauth-routes.js";
6
+ export { getMcpAccessContext } from "./context.js";
4
7
  export { McpAccessPage } from "./pages.js";
5
8
  export { createMcpRoute } from "./route.js";
6
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,kDAAkD;AAClD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,yFAAyF;AACzF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAA8B,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EACL,oBAAoB,EACpB,6BAA6B,EAC7B,uBAAuB,EACvB,mCAAmC,EACnC,iCAAiC,EACjC,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,7 @@
1
+ type SearchParams = Promise<Record<string, string | string[] | undefined>>;
2
+ export interface OAuthConsentPageProps {
3
+ readonly searchParams?: SearchParams;
4
+ }
5
+ export declare function OAuthConsentPage({ searchParams }: OAuthConsentPageProps): Promise<import("react").JSX.Element>;
6
+ export {};
7
+ //# sourceMappingURL=oauth-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-page.d.ts","sourceRoot":"","sources":["../../src/next/oauth-page.tsx"],"names":[],"mappings":"AAiBA,KAAK,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;AAE3E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;CACtC;AAID,wBAAsB,gBAAgB,CAAC,EAAE,YAAY,EAAE,EAAE,qBAAqB,wCA0C7E"}
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // The OAuth consent page, ready to mount with one line:
3
+ // `export { OAuthConsentPage as default } from "@softure-ai/mcp-access/next"`.
4
+ // The authorization endpoint clients send the person to. Without a session it redirects to the
5
+ // login page and back with every parameter (state, challenge, resource). Errors before the client
6
+ // and its redirect URI are confirmed are shown here, never redirected; later ones offer a link back
7
+ // to the client, never an automatic redirect (anyone can register a redirect URI).
8
+ import { requireUser } from "@softure-ai/auth/next";
9
+ import { formatMessage } from "@softure-ai/core";
10
+ import { getSoftureConfig } from "@softure-ai/core/next";
11
+ import { Card } from "@softure-ai/ui";
12
+ import { notFound } from "next/navigation";
13
+ import { getConsentPath, isOAuthEnabled, readAuthorizationParams, validateAuthorizationRequest } from "../server/oauth-http.js";
14
+ import { describeRedirectUri } from "../server/oauth-validation.js";
15
+ import { getMcpAccessMessages, getMcpAccessOptions, getMcpAccessRoutes } from "../server/options.js";
16
+ import { ConsentError, ConsentForm } from "../ui/consent-form.js";
17
+ import { getMcpAccessContext, getRequestOrigins } from "./context.js";
18
+ const LAYOUT_CLASS = "sft:mx-auto sft:box-border sft:w-full sft:sm:max-w-md sft:px-4 sft:py-4";
19
+ export async function OAuthConsentPage({ searchParams }) {
20
+ const config = getSoftureConfig();
21
+ if (!isOAuthEnabled(config))
22
+ notFound();
23
+ const query = (await searchParams) ?? {};
24
+ const params = readAuthorizationParams({ get: (name) => query[name] });
25
+ const user = await requireUser({ next: getConsentPath(config, params), searchParams: query });
26
+ const messages = getMcpAccessMessages(config);
27
+ const origins = await getRequestOrigins(config, getMcpAccessRoutes(config).oauthConsent);
28
+ const outcome = await validateAuthorizationRequest(await getMcpAccessContext(config), params, origins);
29
+ if (outcome.kind !== "valid") {
30
+ const message = outcome.kind === "redirect-error" ? messages.consent.invalidRequest : outcome.reason === "unknown_client" ? messages.consent.unknownClient : messages.consent.redirectMismatch;
31
+ return (_jsx("main", { className: LAYOUT_CLASS, children: _jsx(Card, { title: messages.consent.errorTitle, children: _jsx(ConsentError, { message: message, ...(outcome.kind === "redirect-error" ? { backLocation: outcome.location, backTarget: describeRedirectUri(outcome.redirectUri) } : {}), messages: messages }) }) }));
32
+ }
33
+ const { client, redirectUri, isWriteRequested } = outcome.request;
34
+ return (_jsx("main", { className: LAYOUT_CLASS, children: _jsx(Card, { title: formatMessage(messages.consent.title, { client: client.clientName }), subtitle: messages.consent.lead, children: _jsx(ConsentForm, { action: getMcpAccessRoutes(config).oauthDecision, params: [...params.entries()], clientName: client.clientName, redirectTarget: describeRedirectUri(redirectUri), accountEmail: user.email, isWriteOffered: isWriteRequested && getMcpAccessOptions(config).allowWrites, messages: messages }) }) }));
35
+ }
36
+ //# sourceMappingURL=oauth-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-page.js","sourceRoot":"","sources":["../../src/next/oauth-page.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { answerOAuthPreflight } from "../server/oauth-http.js";
2
+ /**
3
+ * `GET /.well-known/oauth-authorization-server`. Reads the request, so Next never renders it at
4
+ * build time with one origin baked in.
5
+ */
6
+ export declare function getAuthorizationServerMetadataRoute(request: Request): Response;
7
+ /**
8
+ * `GET /.well-known/oauth-protected-resource` and `…/oauth-protected-resource/api/mcp`: the same
9
+ * export at both paths; the request's path picks the variant.
10
+ */
11
+ export declare function getProtectedResourceMetadataRoute(request: Request): Response;
12
+ /** `POST /api/oauth/register`. */
13
+ export declare function registerOAuthClientRoute(request: Request): Promise<Response>;
14
+ /** `POST /api/oauth/token`. */
15
+ export declare function exchangeOAuthTokenRoute(request: Request): Promise<Response>;
16
+ /** `POST /api/oauth/authorize`: the consent form's decision, answered with `303`. */
17
+ export declare function decideOAuthAuthorizationRoute(request: Request): Promise<Response>;
18
+ export { answerOAuthPreflight };
19
+ //# sourceMappingURL=oauth-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-routes.d.ts","sourceRoot":"","sources":["../../src/next/oauth-routes.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,oBAAoB,EAQrB,MAAM,yBAAyB,CAAC;AAiBjC;;;GAGG;AACH,wBAAgB,mCAAmC,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAE9E;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAO5E;AAED,kCAAkC;AAClC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAE5E;AAED,+BAA+B;AAC/B,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAE3E;AAED,qFAAqF;AACrF,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAKjF;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -0,0 +1,53 @@
1
+ // The OAuth routes, each mounted with one line (README §4), e.g.
2
+ // `app/api/oauth/token/route.ts → export { exchangeOAuthTokenRoute as POST, answerOAuthPreflight as OPTIONS } from "@softure-ai/mcp-access/next";`
3
+ // They supply the module context (and, for the decision, the session's user) to the handlers in
4
+ // `/server`. With `oauth.enabled` off every one answers 404.
5
+ import { getCurrentUser } from "@softure-ai/auth/next";
6
+ import { errorLogLabel } from "@softure-ai/core";
7
+ import { getSoftureConfig } from "@softure-ai/core/next";
8
+ import { answerOAuthPreflight, getAuthorizationServerMetadata, getProtectedResourceMetadata, getRootProtectedResourceMetadata, handleAuthorizationDecision, handleClientRegistration, handleTokenRequest, serveDiscoveryDocument, } from "../server/oauth-http.js";
9
+ import { getMcpAccessContext } from "./context.js";
10
+ const UNAVAILABLE = { status: 503, headers: { "cache-control": "no-store" } };
11
+ async function withContext(request, handle) {
12
+ let ctx;
13
+ try {
14
+ ctx = await getMcpAccessContext();
15
+ }
16
+ catch (error) {
17
+ console.error(`@softure-ai/mcp-access: opening the database failed: ${errorLogLabel(error)}`);
18
+ return Response.json({ error: "temporarily_unavailable" }, UNAVAILABLE);
19
+ }
20
+ return handle(ctx, request);
21
+ }
22
+ /**
23
+ * `GET /.well-known/oauth-authorization-server`. Reads the request, so Next never renders it at
24
+ * build time with one origin baked in.
25
+ */
26
+ export function getAuthorizationServerMetadataRoute(request) {
27
+ return serveDiscoveryDocument(getSoftureConfig(), (config, origins) => getAuthorizationServerMetadata(config, origins), request);
28
+ }
29
+ /**
30
+ * `GET /.well-known/oauth-protected-resource` and `…/oauth-protected-resource/api/mcp`: the same
31
+ * export at both paths; the request's path picks the variant.
32
+ */
33
+ export function getProtectedResourceMetadataRoute(request) {
34
+ const isRoot = new URL(request.url).pathname.replace(/\/+$/, "").endsWith("/oauth-protected-resource");
35
+ return serveDiscoveryDocument(getSoftureConfig(), isRoot ? getRootProtectedResourceMetadata : (config, origins) => getProtectedResourceMetadata(config, "endpoint", origins), request);
36
+ }
37
+ /** `POST /api/oauth/register`. */
38
+ export function registerOAuthClientRoute(request) {
39
+ return withContext(request, handleClientRegistration);
40
+ }
41
+ /** `POST /api/oauth/token`. */
42
+ export function exchangeOAuthTokenRoute(request) {
43
+ return withContext(request, handleTokenRequest);
44
+ }
45
+ /** `POST /api/oauth/authorize`: the consent form's decision, answered with `303`. */
46
+ export function decideOAuthAuthorizationRoute(request) {
47
+ return withContext(request, async (ctx, req) => {
48
+ const user = await getCurrentUser();
49
+ return handleAuthorizationDecision(ctx, req, user?.id ?? null);
50
+ });
51
+ }
52
+ export { answerOAuthPreflight };
53
+ //# sourceMappingURL=oauth-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-routes.js","sourceRoot":"","sources":["../../src/next/oauth-routes.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,mJAAmJ;AACnJ,gGAAgG;AAChG,6DAA6D;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EACL,oBAAoB,EACpB,8BAA8B,EAC9B,4BAA4B,EAC5B,gCAAgC,EAChC,2BAA2B,EAC3B,wBAAwB,EACxB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,WAAW,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,eAAe,EAAE,UAAU,EAAE,EAAE,CAAC;AAE9E,KAAK,UAAU,WAAW,CAAC,OAAgB,EAAE,MAAsE;IACjH,IAAI,GAAG,CAAC;IACR,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,mBAAmB,EAAE,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,wDAAwD,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC9F,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,WAAW,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mCAAmC,CAAC,OAAgB;IAClE,OAAO,sBAAsB,CAAC,gBAAgB,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,8BAA8B,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;AACnI,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iCAAiC,CAAC,OAAgB;IAChE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC;IACvG,OAAO,sBAAsB,CAC3B,gBAAgB,EAAE,EAClB,MAAM,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,4BAA4B,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAC1H,OAAO,CACR,CAAC;AACJ,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,wBAAwB,CAAC,OAAgB;IACvD,OAAO,WAAW,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC;AACxD,CAAC;AAED,+BAA+B;AAC/B,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,OAAO,WAAW,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;AAClD,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,6BAA6B,CAAC,OAAgB;IAC5D,OAAO,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAC7C,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;QACpC,OAAO,2BAA2B,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../../src/next/pages.tsx"],"names":[],"mappings":"AAuDA,wBAAsB,aAAa,yCAwBlC"}
1
+ {"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../../src/next/pages.tsx"],"names":[],"mappings":"AAkEA,wBAAsB,aAAa,yCA0BlC"}
@@ -9,10 +9,11 @@ import { formatMessage } from "@softure-ai/core";
9
9
  import { getSoftureConfig } from "@softure-ai/core/next";
10
10
  import { Card } from "@softure-ai/ui";
11
11
  import { getLocalizedText, getMcpAccessMessages, getMcpAccessOptions, getMcpAccessRoutes } from "../server/options.js";
12
+ import { listOAuthGrants } from "../server/oauth.js";
12
13
  import { listAccessTokens } from "../server/tokens.js";
13
14
  import { getAccessTokenStatus } from "../token-status.js";
14
15
  import { TokenManager } from "../ui/token-manager.js";
15
- import { issueTokenAction, revokeTokenAction } from "./actions.js";
16
+ import { issueTokenAction, revokeGrantAction, revokeTokenAction } from "./actions.js";
16
17
  import { getMcpAccessContext } from "./context.js";
17
18
  import { formatDate, formatDateTime } from "./format.js";
18
19
  const LAYOUT_CLASS = "sft:mx-auto sft:box-border sft:w-full sft:sm:max-w-3xl sft:px-4 sft:py-4";
@@ -44,6 +45,15 @@ function toRow(token, now, config, options, messages) {
44
45
  details: [formatMessage(messages.list.createdOn, { date: formatDate(config, token.createdAt) }), expiry, lastUse],
45
46
  };
46
47
  }
48
+ function toGrant(grant, config, options, messages) {
49
+ const lastUse = grant.lastUsedAt === null ? messages.list.neverUsed : formatMessage(messages.list.lastUsed, { date: formatDateTime(config, grant.lastUsedAt) });
50
+ return {
51
+ id: grant.id,
52
+ clientName: grant.clientName,
53
+ scopeText: grant.canWrite && options.allowWrites ? messages.list.readWrite : messages.list.readOnly,
54
+ details: [formatMessage(messages.grants.connectedOn, { date: formatDate(config, grant.createdAt) }), lastUse],
55
+ };
56
+ }
47
57
  function toTool(tool, config, options, messages) {
48
58
  const accessText = tool.access === "read" ? messages.tools.read : options.allowWrites ? messages.tools.write : messages.tools.writeUnavailable;
49
59
  return { name: tool.name, description: getLocalizedText(tool.description, config.locale), accessText };
@@ -56,6 +66,7 @@ export async function McpAccessPage() {
56
66
  const ctx = await getMcpAccessContext(config);
57
67
  const now = ctx.clock.now();
58
68
  const tokens = await listAccessTokens(ctx, user.id);
59
- return (_jsx("main", { className: LAYOUT_CLASS, children: _jsx(Card, { title: messages.page.title, subtitle: messages.page.lead, children: _jsx(TokenManager, { tools: options.tools.map((tool) => toTool(tool, config, options, messages)), tokens: tokens.map((token) => toRow(token, now, config, options, messages)), allowWrites: options.allowWrites, maxTokens: options.maxTokensPerUser, issueAction: issueTokenAction, revokeAction: revokeTokenAction, messages: messages, locale: config.locale }) }) }));
69
+ const grants = options.oauth.enabled ? await listOAuthGrants(ctx, user.id) : null;
70
+ return (_jsx("main", { className: LAYOUT_CLASS, children: _jsx(Card, { title: messages.page.title, subtitle: messages.page.lead, children: _jsx(TokenManager, { tools: options.tools.map((tool) => toTool(tool, config, options, messages)), tokens: tokens.map((token) => toRow(token, now, config, options, messages)), allowWrites: options.allowWrites, maxTokens: options.maxTokensPerUser, issueAction: issueTokenAction, revokeAction: revokeTokenAction, ...(grants === null ? {} : { grants: grants.map((grant) => toGrant(grant, config, options, messages)), revokeGrantAction }), messages: messages, locale: config.locale }) }) }));
60
71
  }
61
72
  //# sourceMappingURL=pages.js.map