@prenta/core 8.6.1 → 8.8.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 (157) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/api/handlers.d.ts.map +1 -1
  3. package/dist/api/handlers.js +4 -0
  4. package/dist/api/handlers.js.map +1 -1
  5. package/dist/api/index.d.ts +2 -0
  6. package/dist/api/index.d.ts.map +1 -1
  7. package/dist/api/index.js +2 -0
  8. package/dist/api/index.js.map +1 -1
  9. package/dist/api/route-helpers/auth.d.ts +24 -2
  10. package/dist/api/route-helpers/auth.d.ts.map +1 -1
  11. package/dist/api/route-helpers/auth.js +93 -1
  12. package/dist/api/route-helpers/auth.js.map +1 -1
  13. package/dist/api/route-helpers.d.ts +1 -1
  14. package/dist/api/route-helpers.d.ts.map +1 -1
  15. package/dist/api/route-helpers.js +1 -1
  16. package/dist/api/route-helpers.js.map +1 -1
  17. package/dist/api/routes/ai-authoring.d.ts.map +1 -1
  18. package/dist/api/routes/ai-authoring.js +8 -3
  19. package/dist/api/routes/ai-authoring.js.map +1 -1
  20. package/dist/api/routes/forms.d.ts.map +1 -1
  21. package/dist/api/routes/forms.js +50 -34
  22. package/dist/api/routes/forms.js.map +1 -1
  23. package/dist/api/routes/globals.d.ts.map +1 -1
  24. package/dist/api/routes/globals.js +42 -3
  25. package/dist/api/routes/globals.js.map +1 -1
  26. package/dist/api/routes/mcp-oauth.d.ts +3 -0
  27. package/dist/api/routes/mcp-oauth.d.ts.map +1 -0
  28. package/dist/api/routes/mcp-oauth.js +143 -0
  29. package/dist/api/routes/mcp-oauth.js.map +1 -0
  30. package/dist/api/routes/preview.d.ts.map +1 -1
  31. package/dist/api/routes/preview.js +43 -2
  32. package/dist/api/routes/preview.js.map +1 -1
  33. package/dist/api/routes/privacy.d.ts +3 -0
  34. package/dist/api/routes/privacy.d.ts.map +1 -0
  35. package/dist/api/routes/privacy.js +44 -0
  36. package/dist/api/routes/privacy.js.map +1 -0
  37. package/dist/api/routes/scheduling.d.ts.map +1 -1
  38. package/dist/api/routes/scheduling.js +4 -1
  39. package/dist/api/routes/scheduling.js.map +1 -1
  40. package/dist/api/routes/seo/handlers/audits.d.ts.map +1 -1
  41. package/dist/api/routes/seo/handlers/audits.js +3 -3
  42. package/dist/api/routes/seo/handlers/audits.js.map +1 -1
  43. package/dist/api/routes/seo/handlers/content.d.ts.map +1 -1
  44. package/dist/api/routes/seo/handlers/content.js +2 -2
  45. package/dist/api/routes/seo/handlers/content.js.map +1 -1
  46. package/dist/api/routes/seo/handlers/issue-helpers.d.ts.map +1 -1
  47. package/dist/api/routes/seo/handlers/issue-helpers.js +2 -2
  48. package/dist/api/routes/seo/handlers/issue-helpers.js.map +1 -1
  49. package/dist/api/routes/seo/handlers/issues-fixes.js +3 -3
  50. package/dist/api/routes/seo/handlers/issues-fixes.js.map +1 -1
  51. package/dist/api/routes/seo/handlers/links.d.ts.map +1 -1
  52. package/dist/api/routes/seo/handlers/links.js +6 -6
  53. package/dist/api/routes/seo/handlers/links.js.map +1 -1
  54. package/dist/api/routes/seo/handlers/proposals.js +2 -2
  55. package/dist/api/routes/seo/handlers/proposals.js.map +1 -1
  56. package/dist/api/routes/seo-public.d.ts.map +1 -1
  57. package/dist/api/routes/seo-public.js +9 -0
  58. package/dist/api/routes/seo-public.js.map +1 -1
  59. package/dist/appearance/index.d.ts +2 -0
  60. package/dist/appearance/index.d.ts.map +1 -1
  61. package/dist/appearance/index.js +1 -0
  62. package/dist/appearance/index.js.map +1 -1
  63. package/dist/appearance/public-theme.d.ts +24 -0
  64. package/dist/appearance/public-theme.d.ts.map +1 -0
  65. package/dist/appearance/public-theme.js +87 -0
  66. package/dist/appearance/public-theme.js.map +1 -0
  67. package/dist/appearance/resolve.d.ts.map +1 -1
  68. package/dist/appearance/resolve.js +3 -0
  69. package/dist/appearance/resolve.js.map +1 -1
  70. package/dist/appearance/types.d.ts +3 -0
  71. package/dist/appearance/types.d.ts.map +1 -1
  72. package/dist/appearance/types.js +0 -14
  73. package/dist/appearance/types.js.map +1 -1
  74. package/dist/db/model-types.d.ts +40 -0
  75. package/dist/db/model-types.d.ts.map +1 -1
  76. package/dist/forms/delivery.d.ts.map +1 -1
  77. package/dist/forms/delivery.js +16 -10
  78. package/dist/forms/delivery.js.map +1 -1
  79. package/dist/forms/encryption.d.ts +4 -2
  80. package/dist/forms/encryption.d.ts.map +1 -1
  81. package/dist/forms/encryption.js +6 -4
  82. package/dist/forms/encryption.js.map +1 -1
  83. package/dist/forms/submission.d.ts.map +1 -1
  84. package/dist/forms/submission.js +17 -10
  85. package/dist/forms/submission.js.map +1 -1
  86. package/dist/generated/browser.d.ts +19 -0
  87. package/dist/generated/client.d.ts +19 -0
  88. package/dist/generated/internal/class.d.ts +33 -0
  89. package/dist/generated/internal/class.js +4 -4
  90. package/dist/generated/internal/prismaNamespace.d.ts +296 -1
  91. package/dist/generated/internal/prismaNamespace.js +65 -1
  92. package/dist/generated/internal/prismaNamespaceBrowser.d.ts +70 -0
  93. package/dist/generated/internal/prismaNamespaceBrowser.js +65 -1
  94. package/dist/generated/models/McpOauthGrant.d.ts +1577 -0
  95. package/dist/generated/models/McpOauthGrant.js +1 -0
  96. package/dist/generated/models/McpOauthRefreshReplay.d.ts +957 -0
  97. package/dist/generated/models/McpOauthRefreshReplay.js +1 -0
  98. package/dist/generated/models/McpOauthTransaction.d.ts +1153 -0
  99. package/dist/generated/models/McpOauthTransaction.js +1 -0
  100. package/dist/generated/models/User.d.ts +279 -0
  101. package/dist/generated/models.d.ts +3 -0
  102. package/dist/index.d.ts +2 -2
  103. package/dist/index.d.ts.map +1 -1
  104. package/dist/index.js +1 -1
  105. package/dist/index.js.map +1 -1
  106. package/dist/mcp/cimd.d.ts +12 -0
  107. package/dist/mcp/cimd.d.ts.map +1 -0
  108. package/dist/mcp/cimd.js +67 -0
  109. package/dist/mcp/cimd.js.map +1 -0
  110. package/dist/mcp/gate.d.ts +11 -0
  111. package/dist/mcp/gate.d.ts.map +1 -0
  112. package/dist/mcp/gate.js +75 -0
  113. package/dist/mcp/gate.js.map +1 -0
  114. package/dist/mcp/memory-grant-store.d.ts +5 -0
  115. package/dist/mcp/memory-grant-store.d.ts.map +1 -0
  116. package/dist/mcp/memory-grant-store.js +44 -0
  117. package/dist/mcp/memory-grant-store.js.map +1 -0
  118. package/dist/mcp/oauth-grants.d.ts +83 -0
  119. package/dist/mcp/oauth-grants.d.ts.map +1 -0
  120. package/dist/mcp/oauth-grants.js +129 -0
  121. package/dist/mcp/oauth-grants.js.map +1 -0
  122. package/dist/mcp/oauth-http.d.ts +43 -0
  123. package/dist/mcp/oauth-http.d.ts.map +1 -0
  124. package/dist/mcp/oauth-http.js +243 -0
  125. package/dist/mcp/oauth-http.js.map +1 -0
  126. package/dist/mcp/oauth-token.d.ts +43 -0
  127. package/dist/mcp/oauth-token.d.ts.map +1 -0
  128. package/dist/mcp/oauth-token.js +78 -0
  129. package/dist/mcp/oauth-token.js.map +1 -0
  130. package/dist/mcp/prisma-store.d.ts +5 -0
  131. package/dist/mcp/prisma-store.d.ts.map +1 -0
  132. package/dist/mcp/prisma-store.js +69 -0
  133. package/dist/mcp/prisma-store.js.map +1 -0
  134. package/dist/mcp/public.d.ts +5 -0
  135. package/dist/mcp/public.d.ts.map +1 -0
  136. package/dist/mcp/public.js +30 -0
  137. package/dist/mcp/public.js.map +1 -0
  138. package/dist/mcp/runtime.d.ts +4 -0
  139. package/dist/mcp/runtime.d.ts.map +1 -0
  140. package/dist/mcp/runtime.js +46 -0
  141. package/dist/mcp/runtime.js.map +1 -0
  142. package/dist/mcp/transactions.d.ts +18 -0
  143. package/dist/mcp/transactions.d.ts.map +1 -0
  144. package/dist/mcp/transactions.js +15 -0
  145. package/dist/mcp/transactions.js.map +1 -0
  146. package/dist/privacy/phi.d.ts +5 -0
  147. package/dist/privacy/phi.d.ts.map +1 -0
  148. package/dist/privacy/phi.js +69 -0
  149. package/dist/privacy/phi.js.map +1 -0
  150. package/dist/seo/document-path.d.ts +13 -0
  151. package/dist/seo/document-path.d.ts.map +1 -1
  152. package/dist/seo/document-path.js +10 -0
  153. package/dist/seo/document-path.js.map +1 -1
  154. package/package.json +3 -3
  155. package/prisma/migrations/0023_mcp_oauth/migration.sql +40 -0
  156. package/prisma/migrations/0024_mcp_oauth_transactions/migration.sql +16 -0
  157. package/prisma/schema.prisma +58 -0
@@ -0,0 +1,43 @@
1
+ import { type ClientMetadata } from './cimd.js';
2
+ import { type OauthGrantStore } from './oauth-grants.js';
3
+ import type { OauthTransaction, TransactionStore } from './transactions.js';
4
+ export type OauthUser = {
5
+ id: string;
6
+ role: string;
7
+ active: boolean;
8
+ };
9
+ export type McpOauthRuntime = {
10
+ siteUrl: string;
11
+ adminPath: string;
12
+ secret: string;
13
+ grants: OauthGrantStore;
14
+ transactions: TransactionStore;
15
+ loadUser: (userId: string) => Promise<OauthUser | null>;
16
+ fetchClient?: (clientId: string) => Promise<ClientMetadata | {
17
+ error: string;
18
+ }>;
19
+ now?: () => Date;
20
+ allowAttempt?: (key: string) => boolean;
21
+ };
22
+ export declare function mcpResourceMetadata(runtime: McpOauthRuntime): Response;
23
+ export declare function mcpAuthorizationServerMetadata(runtime: McpOauthRuntime): Response;
24
+ export declare function beginAuthorization(request: Request, runtime: McpOauthRuntime): Promise<Response>;
25
+ export declare function readConsentTransaction(txnId: string, runtime: McpOauthRuntime): Promise<{
26
+ transaction: OauthTransaction;
27
+ redirectHost: string;
28
+ } | null>;
29
+ export declare function completeConsent(input: {
30
+ txnId: string;
31
+ userId: string;
32
+ allow: boolean;
33
+ }, runtime: McpOauthRuntime): Promise<{
34
+ redirectUrl: string;
35
+ } | {
36
+ error: string;
37
+ }>;
38
+ export declare function handleTokenRequest(request: Request, runtime: McpOauthRuntime): Promise<Response>;
39
+ export declare function mcpBearerStatus(token: string, runtime: McpOauthRuntime): Promise<{
40
+ userId: string;
41
+ role: string;
42
+ } | 'insufficient_scope' | null>;
43
+ //# sourceMappingURL=oauth-http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-http.d.ts","sourceRoot":"","sources":["../../src/mcp/oauth-http.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,WAAW,CAAA;AACpE,OAAO,EAOL,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAK3E,MAAM,MAAM,SAAS,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAA;AAErE,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,eAAe,CAAA;IACvB,YAAY,EAAE,gBAAgB,CAAA;IAC9B,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;IACvD,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC/E,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;IAChB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;CACxC,CAAA;AAgCD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAQtE;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAcjF;AAQD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,QAAQ,CAAC,CA4CnB;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC;IAAE,WAAW,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAIzE;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,EACxD,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAgCtD;AAoBD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,QAAQ,CAAC,CAqDnB;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,oBAAoB,GAAG,IAAI,CAAC,CAiBzE"}
@@ -0,0 +1,243 @@
1
+ import { editorialRoleForApiKey } from '../api/route-helpers/auth.js';
2
+ import { fetchClientMetadata } from './cimd.js';
3
+ import { canonicalMcpResource, exchangeAuthorizationCode, issueAuthorizationCode, newSecret, redirectAllowed, rotateRefreshToken, } from './oauth-grants.js';
4
+ import { MCP_CONTENT_SCOPE, signMcpAccessToken, verifyMcpAccessToken } from './oauth-token.js';
5
+ const TXN_TTL_MS = 10 * 60 * 1000;
6
+ const attempts = new Map();
7
+ function nowOf(runtime) {
8
+ return runtime.now?.() ?? new Date();
9
+ }
10
+ function clientOf(runtime) {
11
+ return runtime.fetchClient ?? ((clientId) => fetchClientMetadata(clientId));
12
+ }
13
+ function allowOauthAttempt(key, limit = 30) {
14
+ const now = Date.now();
15
+ const bucket = attempts.get(key);
16
+ if (!bucket || bucket.reset < now) {
17
+ attempts.set(key, { n: 1, reset: now + 60_000 });
18
+ return true;
19
+ }
20
+ bucket.n += 1;
21
+ return bucket.n <= limit;
22
+ }
23
+ function noStore(body, status = 200, extra) {
24
+ return Response.json(body, {
25
+ status,
26
+ headers: { 'cache-control': 'no-store', ...Object.fromEntries(new Headers(extra)) },
27
+ });
28
+ }
29
+ function issuer(runtime) {
30
+ return runtime.siteUrl.replace(/\/+$/, '');
31
+ }
32
+ export function mcpResourceMetadata(runtime) {
33
+ const site = issuer(runtime);
34
+ return Response.json({
35
+ resource: canonicalMcpResource(site),
36
+ authorization_servers: [site],
37
+ scopes_supported: [MCP_CONTENT_SCOPE],
38
+ bearer_methods_supported: ['header'],
39
+ });
40
+ }
41
+ export function mcpAuthorizationServerMetadata(runtime) {
42
+ const site = issuer(runtime);
43
+ return Response.json({
44
+ issuer: site,
45
+ authorization_endpoint: `${site}/oauth/authorize`,
46
+ token_endpoint: `${site}/oauth/token`,
47
+ response_types_supported: ['code'],
48
+ grant_types_supported: ['authorization_code', 'refresh_token'],
49
+ code_challenge_methods_supported: ['S256'],
50
+ token_endpoint_auth_methods_supported: ['none'],
51
+ client_id_metadata_document_supported: true,
52
+ authorization_response_iss_parameter_supported: true,
53
+ scopes_supported: [MCP_CONTENT_SCOPE],
54
+ });
55
+ }
56
+ function redirectTarget(uri, params) {
57
+ const url = new URL(uri);
58
+ for (const [key, value] of Object.entries(params))
59
+ url.searchParams.set(key, value);
60
+ return url.toString();
61
+ }
62
+ export async function beginAuthorization(request, runtime) {
63
+ const ip = request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() || 'unknown';
64
+ if (!(runtime.allowAttempt ?? allowOauthAttempt)(`authorize:${ip}`)) {
65
+ return noStore({ error: 'slow_down' }, 429);
66
+ }
67
+ const url = new URL(request.url);
68
+ const clientId = url.searchParams.get('client_id') ?? '';
69
+ const redirectUri = url.searchParams.get('redirect_uri') ?? '';
70
+ const challenge = url.searchParams.get('code_challenge') ?? '';
71
+ const method = url.searchParams.get('code_challenge_method') ?? '';
72
+ const resource = url.searchParams.get('resource') ?? '';
73
+ const responseType = url.searchParams.get('response_type') ?? '';
74
+ const state = url.searchParams.get('state');
75
+ const scope = url.searchParams.get('scope') ?? MCP_CONTENT_SCOPE;
76
+ const expected = canonicalMcpResource(issuer(runtime));
77
+ if (responseType !== 'code' || method !== 'S256' || !challenge) {
78
+ return noStore({ error: 'invalid_request' }, 400);
79
+ }
80
+ if (scope !== MCP_CONTENT_SCOPE)
81
+ return noStore({ error: 'invalid_scope' }, 400);
82
+ if (resource !== expected)
83
+ return noStore({ error: 'invalid_target' }, 400);
84
+ const meta = await clientOf(runtime)(clientId);
85
+ if ('error' in meta)
86
+ return noStore({ error: meta.error }, 400);
87
+ if (!redirectAllowed(redirectUri, meta.redirectUris)) {
88
+ return noStore({ error: 'invalid_request', error_description: 'redirect_uri mismatch' }, 400);
89
+ }
90
+ const txn = {
91
+ id: newSecret(),
92
+ clientId,
93
+ clientName: meta.clientName,
94
+ redirectUri,
95
+ resource,
96
+ scope,
97
+ codeChallenge: challenge,
98
+ state,
99
+ expiresAt: new Date(nowOf(runtime).getTime() + TXN_TTL_MS),
100
+ };
101
+ await runtime.transactions.put(txn);
102
+ const admin = runtime.adminPath.startsWith('/') ? runtime.adminPath : `/${runtime.adminPath}`;
103
+ const next = new URL(`${issuer(runtime)}${admin}/mcp/consent`);
104
+ next.searchParams.set('txn', txn.id);
105
+ return Response.redirect(next.toString(), 302);
106
+ }
107
+ export async function readConsentTransaction(txnId, runtime) {
108
+ const txn = await runtime.transactions.get(txnId);
109
+ if (!txn || txn.expiresAt.getTime() <= nowOf(runtime).getTime())
110
+ return null;
111
+ return { transaction: txn, redirectHost: new URL(txn.redirectUri).host };
112
+ }
113
+ export async function completeConsent(input, runtime) {
114
+ const txn = await runtime.transactions.get(input.txnId);
115
+ if (!txn || txn.expiresAt.getTime() <= nowOf(runtime).getTime())
116
+ return { error: 'expired' };
117
+ await runtime.transactions.delete(input.txnId);
118
+ const iss = issuer(runtime);
119
+ if (!input.allow) {
120
+ return {
121
+ redirectUrl: redirectTarget(txn.redirectUri, {
122
+ error: 'access_denied',
123
+ ...(txn.state ? { state: txn.state } : {}),
124
+ iss,
125
+ }),
126
+ };
127
+ }
128
+ const user = await runtime.loadUser(input.userId);
129
+ if (!user?.active)
130
+ return { error: 'forbidden' };
131
+ const { code } = await issueAuthorizationCode(runtime.grants, {
132
+ userId: user.id,
133
+ clientId: txn.clientId,
134
+ redirectUri: txn.redirectUri,
135
+ resource: txn.resource,
136
+ scope: txn.scope,
137
+ codeChallenge: txn.codeChallenge,
138
+ now: nowOf(runtime),
139
+ });
140
+ return {
141
+ redirectUrl: redirectTarget(txn.redirectUri, {
142
+ code,
143
+ ...(txn.state ? { state: txn.state } : {}),
144
+ iss,
145
+ }),
146
+ };
147
+ }
148
+ async function issueAccess(runtime, userId, scope) {
149
+ const user = await runtime.loadUser(userId);
150
+ if (!user?.active)
151
+ return null;
152
+ const role = editorialRoleForApiKey(user.role, {
153
+ collections: ['*'],
154
+ actions: ['read', 'create', 'update'],
155
+ });
156
+ const signed = await signMcpAccessToken({
157
+ secret: runtime.secret,
158
+ issuer: issuer(runtime),
159
+ resource: canonicalMcpResource(issuer(runtime)),
160
+ userId,
161
+ role,
162
+ scope,
163
+ });
164
+ return signed.token;
165
+ }
166
+ export async function handleTokenRequest(request, runtime) {
167
+ const ip = request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() || 'unknown';
168
+ if (!(runtime.allowAttempt ?? allowOauthAttempt)(`token:${ip}`)) {
169
+ return noStore({ error: 'slow_down' }, 429);
170
+ }
171
+ const body = new URLSearchParams(await request.text());
172
+ const grantType = body.get('grant_type') ?? '';
173
+ const clientId = body.get('client_id') ?? '';
174
+ const resource = body.get('resource') ?? '';
175
+ const expected = canonicalMcpResource(issuer(runtime));
176
+ if (resource !== expected)
177
+ return noStore({ error: 'invalid_target' }, 400);
178
+ if (grantType === 'authorization_code') {
179
+ const exchanged = await exchangeAuthorizationCode(runtime.grants, {
180
+ code: body.get('code') ?? '',
181
+ verifier: body.get('code_verifier') ?? '',
182
+ clientId,
183
+ redirectUri: body.get('redirect_uri') ?? '',
184
+ resource,
185
+ now: nowOf(runtime),
186
+ });
187
+ if (!exchanged.ok)
188
+ return noStore({ error: 'invalid_grant' }, 400);
189
+ const access = await issueAccess(runtime, exchanged.grant.userId, exchanged.grant.scope);
190
+ if (!access)
191
+ return noStore({ error: 'invalid_grant' }, 400);
192
+ return noStore({
193
+ access_token: access,
194
+ token_type: 'Bearer',
195
+ expires_in: 15 * 60,
196
+ refresh_token: exchanged.refreshToken,
197
+ scope: exchanged.grant.scope,
198
+ });
199
+ }
200
+ if (grantType === 'refresh_token') {
201
+ const rotated = await rotateRefreshToken(runtime.grants, {
202
+ refreshToken: body.get('refresh_token') ?? '',
203
+ clientId,
204
+ resource,
205
+ now: nowOf(runtime),
206
+ });
207
+ if (!rotated.ok)
208
+ return noStore({ error: 'invalid_grant' }, 400);
209
+ const access = await issueAccess(runtime, rotated.grant.userId, rotated.grant.scope);
210
+ if (!access)
211
+ return noStore({ error: 'invalid_grant' }, 400);
212
+ return noStore({
213
+ access_token: access,
214
+ token_type: 'Bearer',
215
+ expires_in: 15 * 60,
216
+ refresh_token: rotated.refreshToken,
217
+ scope: rotated.grant.scope,
218
+ });
219
+ }
220
+ return noStore({ error: 'unsupported_grant_type' }, 400);
221
+ }
222
+ export async function mcpBearerStatus(token, runtime) {
223
+ const claims = await verifyMcpAccessToken({
224
+ token,
225
+ secret: runtime.secret,
226
+ resource: canonicalMcpResource(issuer(runtime)),
227
+ });
228
+ if (!claims)
229
+ return null;
230
+ if (claims.scope !== MCP_CONTENT_SCOPE)
231
+ return 'insufficient_scope';
232
+ const user = await runtime.loadUser(claims.userId);
233
+ if (!user?.active)
234
+ return null;
235
+ return {
236
+ userId: user.id,
237
+ role: editorialRoleForApiKey(user.role, {
238
+ collections: ['*'],
239
+ actions: ['read', 'create', 'update'],
240
+ }),
241
+ };
242
+ }
243
+ //# sourceMappingURL=oauth-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-http.js","sourceRoot":"","sources":["../../src/mcp/oauth-http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ export declare const MCP_CONTENT_SCOPE = "content";
2
+ export declare const MCP_CONTENT_KEY_SCOPES: {
3
+ collections: string[];
4
+ actions: readonly ["read", "create", "update"];
5
+ globals: string[];
6
+ media: boolean;
7
+ };
8
+ export type McpAccessClaims = {
9
+ userId: string;
10
+ role: string;
11
+ scope: string;
12
+ jti: string;
13
+ };
14
+ export declare function signMcpAccessToken(input: {
15
+ secret: string;
16
+ issuer: string;
17
+ resource: string;
18
+ userId: string;
19
+ role: string;
20
+ scope: string;
21
+ }): Promise<{
22
+ token: string;
23
+ jti: string;
24
+ }>;
25
+ export declare function verifyMcpAccessToken(input: {
26
+ token: string;
27
+ secret: string;
28
+ resource: string;
29
+ }): Promise<McpAccessClaims | null>;
30
+ /** Short-lived assertion used only inside this process. Never returned to a client. */
31
+ export declare function signMcpInternalToken(input: {
32
+ secret: string;
33
+ userId: string;
34
+ role: string;
35
+ }): Promise<string>;
36
+ export declare function verifyMcpInternalToken(input: {
37
+ token: string;
38
+ secret: string;
39
+ }): Promise<{
40
+ userId: string;
41
+ role: string;
42
+ } | null>;
43
+ //# sourceMappingURL=oauth-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-token.d.ts","sourceRoot":"","sources":["../../src/mcp/oauth-token.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,iBAAiB,YAAY,CAAA;AAE1C,eAAO,MAAM,sBAAsB;;;;;CAKlC,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAY1C;AAED,wBAAsB,oBAAoB,CAAC,KAAK,EAAE;IAChD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAclC;AAED,uFAAuF;AACvF,wBAAsB,oBAAoB,CAAC,KAAK,EAAE;IAChD,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlB;AAED,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IAClD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAenD"}
@@ -0,0 +1,78 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import * as jose from 'jose';
3
+ const ACCESS_TYP = 'mcp-access+jwt';
4
+ const INTERNAL_TYP = 'mcp-internal+jwt';
5
+ const ACCESS_TTL = '15m';
6
+ const INTERNAL_AUDIENCE = 'prenta-cms-mcp-internal';
7
+ export const MCP_CONTENT_SCOPE = 'content';
8
+ export const MCP_CONTENT_KEY_SCOPES = {
9
+ collections: ['*'],
10
+ actions: ['read', 'create', 'update'],
11
+ globals: ['*'],
12
+ media: true,
13
+ };
14
+ export async function signMcpAccessToken(input) {
15
+ const jti = randomBytes(16).toString('hex');
16
+ const token = await new jose.SignJWT({ role: input.role, scope: input.scope })
17
+ .setProtectedHeader({ alg: 'HS256', typ: ACCESS_TYP })
18
+ .setSubject(input.userId)
19
+ .setIssuer(input.issuer)
20
+ .setAudience(input.resource)
21
+ .setJti(jti)
22
+ .setIssuedAt()
23
+ .setExpirationTime(ACCESS_TTL)
24
+ .sign(new TextEncoder().encode(input.secret));
25
+ return { token, jti };
26
+ }
27
+ export async function verifyMcpAccessToken(input) {
28
+ try {
29
+ const { payload } = await jose.jwtVerify(input.token, new TextEncoder().encode(input.secret), {
30
+ algorithms: ['HS256'],
31
+ audience: input.resource,
32
+ typ: ACCESS_TYP,
33
+ });
34
+ if (typeof payload.sub !== 'string' || payload.sub.length === 0)
35
+ return null;
36
+ if (typeof payload.role !== 'string' || typeof payload.scope !== 'string')
37
+ return null;
38
+ if (typeof payload.jti !== 'string')
39
+ return null;
40
+ return { userId: payload.sub, role: payload.role, scope: payload.scope, jti: payload.jti };
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ /** Short-lived assertion used only inside this process. Never returned to a client. */
47
+ export async function signMcpInternalToken(input) {
48
+ return new jose.SignJWT({ role: input.role, scope: MCP_CONTENT_SCOPE })
49
+ .setProtectedHeader({ alg: 'HS256', typ: INTERNAL_TYP })
50
+ .setSubject(input.userId)
51
+ .setIssuer('prenta-cms')
52
+ .setAudience(INTERNAL_AUDIENCE)
53
+ .setJti(randomBytes(16).toString('hex'))
54
+ .setIssuedAt()
55
+ .setExpirationTime('60s')
56
+ .sign(new TextEncoder().encode(input.secret));
57
+ }
58
+ export async function verifyMcpInternalToken(input) {
59
+ try {
60
+ const { payload } = await jose.jwtVerify(input.token, new TextEncoder().encode(input.secret), {
61
+ algorithms: ['HS256'],
62
+ audience: INTERNAL_AUDIENCE,
63
+ issuer: 'prenta-cms',
64
+ typ: INTERNAL_TYP,
65
+ });
66
+ if (typeof payload.sub !== 'string' || payload.sub.length === 0)
67
+ return null;
68
+ if (payload.scope !== MCP_CONTENT_SCOPE)
69
+ return null;
70
+ if (typeof payload.role !== 'string')
71
+ return null;
72
+ return { userId: payload.sub, role: payload.role };
73
+ }
74
+ catch {
75
+ return null;
76
+ }
77
+ }
78
+ //# sourceMappingURL=oauth-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-token.js","sourceRoot":"","sources":["../../src/mcp/oauth-token.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { OauthGrantStore } from './oauth-grants.js';
2
+ import type { TransactionStore } from './transactions.js';
3
+ export declare function prismaGrantStore(): OauthGrantStore;
4
+ export declare function prismaTransactionStore(): TransactionStore;
5
+ //# sourceMappingURL=prisma-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma-store.d.ts","sourceRoot":"","sources":["../../src/mcp/prisma-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACrE,OAAO,KAAK,EAAoB,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AA8B3E,wBAAgB,gBAAgB,IAAI,eAAe,CA8ClD;AAED,wBAAgB,sBAAsB,IAAI,gBAAgB,CAczD"}
@@ -0,0 +1,69 @@
1
+ import { getDB } from '../db.js';
2
+ function db() {
3
+ return getDB();
4
+ }
5
+ export function prismaGrantStore() {
6
+ return {
7
+ async insert(row) {
8
+ await db().mcpOauthGrant.create({ data: row });
9
+ },
10
+ async findByCodeHash(hash) {
11
+ return db().mcpOauthGrant.findUnique({ where: { codeHash: hash } });
12
+ },
13
+ async save(row) {
14
+ await db().mcpOauthGrant.update({
15
+ where: { id: row.id },
16
+ data: {
17
+ codeConsumedAt: row.codeConsumedAt,
18
+ refreshHash: row.refreshHash,
19
+ refreshExpiresAt: row.refreshExpiresAt,
20
+ revokedAt: row.revokedAt,
21
+ },
22
+ });
23
+ },
24
+ async findByRefreshHash(hash) {
25
+ const row = await db().mcpOauthGrant.findUnique({ where: { refreshHash: hash } });
26
+ if (!row || row.revokedAt)
27
+ return null;
28
+ return row;
29
+ },
30
+ async findReplay(hash) {
31
+ return db().mcpOauthRefreshReplay.findUnique({ where: { hash } });
32
+ },
33
+ async rememberReplay(hash, familyId) {
34
+ await db().mcpOauthRefreshReplay.create({ data: { hash, familyId } });
35
+ },
36
+ async revokeFamily(familyId, now) {
37
+ await db().mcpOauthGrant.updateMany({
38
+ where: { familyId, revokedAt: null },
39
+ data: { revokedAt: now },
40
+ });
41
+ },
42
+ async listForUser(userId) {
43
+ return db().mcpOauthGrant.findMany({ where: { userId } });
44
+ },
45
+ async revokeById(id, userId, now) {
46
+ const row = await db().mcpOauthGrant.findUnique({ where: { id } });
47
+ if (!row || row.userId !== userId || row.revokedAt)
48
+ return false;
49
+ await db().mcpOauthGrant.update({ where: { id }, data: { revokedAt: now } });
50
+ return true;
51
+ },
52
+ };
53
+ }
54
+ export function prismaTransactionStore() {
55
+ return {
56
+ async put(row) {
57
+ await db().mcpOauthTransaction.create({ data: row });
58
+ },
59
+ async get(id) {
60
+ return db().mcpOauthTransaction.findUnique({ where: { id } });
61
+ },
62
+ async delete(id) {
63
+ await db()
64
+ .mcpOauthTransaction.delete({ where: { id } })
65
+ .catch(() => { });
66
+ },
67
+ };
68
+ }
69
+ //# sourceMappingURL=prisma-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma-store.js","sourceRoot":"","sources":["../../src/mcp/prisma-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function handleMcpProtectedResource(): Response;
2
+ export declare function handleMcpAuthorizationServer(): Response;
3
+ export declare function handleMcpAuthorize(request: Request): Promise<Response>;
4
+ export declare function handleMcpToken(request: Request): Promise<Response>;
5
+ //# sourceMappingURL=public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/mcp/public.ts"],"names":[],"mappings":"AAeA,wBAAgB,0BAA0B,IAAI,QAAQ,CAIrD;AAED,wBAAgB,4BAA4B,IAAI,QAAQ,CAIvD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAItE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAIlE"}
@@ -0,0 +1,30 @@
1
+ import { beginAuthorization, handleTokenRequest, mcpAuthorizationServerMetadata, mcpResourceMetadata, } from './oauth-http.js';
2
+ import { mcpOauthRuntime } from './runtime.js';
3
+ function unavailable() {
4
+ return Response.json({ error: 'server_error', error_description: 'MCP site URL is not configured' }, { status: 500, headers: { 'cache-control': 'no-store' } });
5
+ }
6
+ export function handleMcpProtectedResource() {
7
+ const runtime = mcpOauthRuntime();
8
+ if (!runtime)
9
+ return unavailable();
10
+ return mcpResourceMetadata(runtime);
11
+ }
12
+ export function handleMcpAuthorizationServer() {
13
+ const runtime = mcpOauthRuntime();
14
+ if (!runtime)
15
+ return unavailable();
16
+ return mcpAuthorizationServerMetadata(runtime);
17
+ }
18
+ export function handleMcpAuthorize(request) {
19
+ const runtime = mcpOauthRuntime();
20
+ if (!runtime)
21
+ return Promise.resolve(unavailable());
22
+ return beginAuthorization(request, runtime);
23
+ }
24
+ export function handleMcpToken(request) {
25
+ const runtime = mcpOauthRuntime();
26
+ if (!runtime)
27
+ return Promise.resolve(unavailable());
28
+ return handleTokenRequest(request, runtime);
29
+ }
30
+ //# sourceMappingURL=public.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.js","sourceRoot":"","sources":["../../src/mcp/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,8BAA8B,EAC9B,mBAAmB,GACpB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAE9C,SAAS,WAAW;IAClB,OAAO,QAAQ,CAAC,IAAI,CAClB,EAAE,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,gCAAgC,EAAE,EAC9E,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,eAAe,EAAE,UAAU,EAAE,EAAE,CAC1D,CAAA;AACH,CAAC;AAED,MAAM,UAAU,0BAA0B;IACxC,MAAM,OAAO,GAAG,eAAe,EAAE,CAAA;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,WAAW,EAAE,CAAA;IAClC,OAAO,mBAAmB,CAAC,OAAO,CAAC,CAAA;AACrC,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,MAAM,OAAO,GAAG,eAAe,EAAE,CAAA;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,WAAW,EAAE,CAAA;IAClC,OAAO,8BAA8B,CAAC,OAAO,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,MAAM,OAAO,GAAG,eAAe,EAAE,CAAA;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;IACnD,OAAO,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,OAAO,GAAG,eAAe,EAAE,CAAA;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;IACnD,OAAO,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AAC7C,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { McpOauthRuntime } from './oauth-http.js';
2
+ export declare function mcpSiteUrl(): string | null;
3
+ export declare function mcpOauthRuntime(): McpOauthRuntime | null;
4
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/mcp/runtime.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAa,MAAM,iBAAiB,CAAA;AAuBjE,wBAAgB,UAAU,IAAI,MAAM,GAAG,IAAI,CAM1C;AAED,wBAAgB,eAAe,IAAI,eAAe,GAAG,IAAI,CA4BxD"}
@@ -0,0 +1,46 @@
1
+ import { getAdminPath, getSessionSecret } from '../api/route-helpers/auth.js';
2
+ import { getPrentaConfig } from '../config/runtime.js';
3
+ import { getDB } from '../db.js';
4
+ import { prismaGrantStore, prismaTransactionStore } from './prisma-store.js';
5
+ export function mcpSiteUrl() {
6
+ const fromEnv = process.env.NEXT_PUBLIC_SITE_URL?.trim();
7
+ if (fromEnv)
8
+ return fromEnv.replace(/\/+$/, '');
9
+ const fromConfig = getPrentaConfig()?.seo?.siteUrl?.trim();
10
+ if (fromConfig)
11
+ return fromConfig.replace(/\/+$/, '');
12
+ return null;
13
+ }
14
+ export function mcpOauthRuntime() {
15
+ const siteUrl = mcpSiteUrl();
16
+ if (!siteUrl)
17
+ return null;
18
+ let secret = '';
19
+ try {
20
+ secret = getSessionSecret();
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ return {
26
+ siteUrl,
27
+ adminPath: getAdminPath(),
28
+ secret,
29
+ grants: prismaGrantStore(),
30
+ transactions: prismaTransactionStore(),
31
+ loadUser: async (userId) => {
32
+ const user = await getDB().user.findUnique({
33
+ where: { id: userId },
34
+ select: { id: true, role: true, isActive: true, suspendedAt: true, lockedAt: true },
35
+ });
36
+ if (!user)
37
+ return null;
38
+ return {
39
+ id: user.id,
40
+ role: user.role,
41
+ active: user.isActive !== false && !user.suspendedAt && !user.lockedAt,
42
+ };
43
+ },
44
+ };
45
+ }
46
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/mcp/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAwB5E,MAAM,UAAU,UAAU;IACxB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,EAAE,CAAA;IACxD,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC/C,MAAM,UAAU,GAAG,eAAe,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC1D,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IACrD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAC5B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAA;IACzB,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,IAAI,CAAC;QACH,MAAM,GAAG,gBAAgB,EAAE,CAAA;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO;QACL,OAAO;QACP,SAAS,EAAE,YAAY,EAAE;QACzB,MAAM;QACN,MAAM,EAAE,gBAAgB,EAAE;QAC1B,YAAY,EAAE,sBAAsB,EAAE;QACtC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAA6B,EAAE;YACpD,MAAM,IAAI,GAAG,MAAM,KAAK,EAAU,CAAC,IAAI,CAAC,UAAU,CAAC;gBACjD,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;gBACrB,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;aACpF,CAAC,CAAA;YACF,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAA;YACtB,OAAO;gBACL,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM,EAAE,IAAI,CAAC,QAAQ,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,QAAQ;aACvE,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}