@memberjunction/core-entities-server 6.1.0-edge.2 → 6.1.0-edge.4
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.
- package/LICENSE +180 -4
- package/README.md +1 -1
- package/dist/custom/MJActionEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJActionEntityServer.server.js +4 -3
- package/dist/custom/MJActionEntityServer.server.js.map +1 -1
- package/dist/custom/MJCompanyIntegrationEntityServer.server.d.ts +36 -21
- package/dist/custom/MJCompanyIntegrationEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJCompanyIntegrationEntityServer.server.js +37 -51
- package/dist/custom/MJCompanyIntegrationEntityServer.server.js.map +1 -1
- package/dist/custom/MJMaterializedResultEntityServer.server.d.ts +23 -0
- package/dist/custom/MJMaterializedResultEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJMaterializedResultEntityServer.server.js +64 -0
- package/dist/custom/MJMaterializedResultEntityServer.server.js.map +1 -0
- package/dist/custom/MJVectorIndexEntityServer.server.d.ts +9 -2
- package/dist/custom/MJVectorIndexEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJVectorIndexEntityServer.server.js +25 -7
- package/dist/custom/MJVectorIndexEntityServer.server.js.map +1 -1
- package/dist/engines/IdentityClaimEngineServer.d.ts +147 -0
- package/dist/engines/IdentityClaimEngineServer.d.ts.map +1 -0
- package/dist/engines/IdentityClaimEngineServer.js +555 -0
- package/dist/engines/IdentityClaimEngineServer.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +29 -26
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Server-side Identity Claim Engine
|
|
3
|
+
*
|
|
4
|
+
* Implements server-only identity claim lifecycle operations:
|
|
5
|
+
* - Claim creation and persistence
|
|
6
|
+
* - Automatic claimant email notification via MJ Communications Framework
|
|
7
|
+
* - Magic link verification and driver OnClaim execution
|
|
8
|
+
* - Claim revocation and expiration handling
|
|
9
|
+
*
|
|
10
|
+
* @module @memberjunction/core-entities-server/IdentityClaimEngineServer
|
|
11
|
+
*/
|
|
12
|
+
import * as crypto from 'crypto';
|
|
13
|
+
import { BaseSingleton, EscapeSQLString, UUIDsEqual } from '@memberjunction/global';
|
|
14
|
+
import { LogError, LogStatus, Metadata, RunView } from '@memberjunction/core';
|
|
15
|
+
import { IdentityClaimEngine } from '@memberjunction/core-entities';
|
|
16
|
+
import { UserCache } from '@memberjunction/generic-database-provider';
|
|
17
|
+
import { CommunicationEngine } from '@memberjunction/communication-engine';
|
|
18
|
+
import { Message } from '@memberjunction/communication-types';
|
|
19
|
+
import { TemplateEngineServer } from '@memberjunction/templates';
|
|
20
|
+
/**
|
|
21
|
+
* Server-side Identity Claim engine — the ONLY place the claim lifecycle is implemented.
|
|
22
|
+
*
|
|
23
|
+
* Uses containment rather than inheritance, the same split as `AIEngine` / `AIEngineBase`: an
|
|
24
|
+
* instance of the client+server `IdentityClaimEngine` is held via {@link Base} and its cached
|
|
25
|
+
* members (claim types, lookups, driver resolution, email normalization) are proxied below, so
|
|
26
|
+
* `IdentityClaimEngineServer.Instance.X` reaches the whole surface. When a public member is added
|
|
27
|
+
* to `IdentityClaimEngine`, add a proxy here.
|
|
28
|
+
*
|
|
29
|
+
* Creation, redemption and revocation live here and nowhere else, because each depends on
|
|
30
|
+
* something a browser cannot do: `crypto.randomBytes` token generation and SHA-256 hashing,
|
|
31
|
+
* `timingSafeEqual` comparison, an atomic compare-and-swap issued as raw SQL, and email dispatch
|
|
32
|
+
* via MJ Communications.
|
|
33
|
+
*
|
|
34
|
+
* @description ONLY USE ON SERVER-SIDE. For claim-type metadata only, use `IdentityClaimEngine`,
|
|
35
|
+
* which is safe in any host.
|
|
36
|
+
*/
|
|
37
|
+
export class IdentityClaimEngineServer extends BaseSingleton {
|
|
38
|
+
constructor() {
|
|
39
|
+
super();
|
|
40
|
+
this._provider = null;
|
|
41
|
+
}
|
|
42
|
+
static get Instance() {
|
|
43
|
+
return super.getInstance();
|
|
44
|
+
}
|
|
45
|
+
// ------------------------------------------------------------------
|
|
46
|
+
// Contained base engine + proxied members
|
|
47
|
+
// ------------------------------------------------------------------
|
|
48
|
+
/**
|
|
49
|
+
* The contained client+server engine that owns all cached claim-type metadata.
|
|
50
|
+
*/
|
|
51
|
+
get Base() {
|
|
52
|
+
return IdentityClaimEngine.Instance;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The metadata provider this engine operates under.
|
|
56
|
+
*
|
|
57
|
+
* This class is a process-wide singleton (`BaseSingleton` keys on class name), so it cannot
|
|
58
|
+
* own a provider the way a `BaseEngine` subclass does — one instance serves every connection
|
|
59
|
+
* in the process. Callers that have a request-scoped provider should pass it explicitly to
|
|
60
|
+
* the method they are calling; this settable accessor exists for hosts that bind one at
|
|
61
|
+
* startup, and falls back to the global default only when nothing has been supplied.
|
|
62
|
+
*
|
|
63
|
+
* Same shape as `AIEngine.Provider` — which `QueryEngineServer` and `ComponentMetadataEngineServer`
|
|
64
|
+
* both cite as the pattern to follow — and structurally exempt from the multi-provider
|
|
65
|
+
* compliance scanner, so it needs no `global-provider-ok` suppression.
|
|
66
|
+
*/
|
|
67
|
+
get Provider() {
|
|
68
|
+
return this._provider ?? new Metadata();
|
|
69
|
+
}
|
|
70
|
+
set Provider(value) {
|
|
71
|
+
this._provider = value;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Ensures metadata is configured and loaded
|
|
75
|
+
*/
|
|
76
|
+
async Config(forceRefresh, contextUser, provider) {
|
|
77
|
+
if (provider) {
|
|
78
|
+
this._provider = provider;
|
|
79
|
+
}
|
|
80
|
+
await this.Base.Config(forceRefresh, contextUser, provider);
|
|
81
|
+
}
|
|
82
|
+
/** All loaded Identity Claim Types */
|
|
83
|
+
get ClaimTypes() {
|
|
84
|
+
return this.Base.ClaimTypes;
|
|
85
|
+
}
|
|
86
|
+
/** Finds a claim type by name (case-insensitive) */
|
|
87
|
+
GetClaimTypeByName(name) {
|
|
88
|
+
return this.Base.GetClaimTypeByName(name);
|
|
89
|
+
}
|
|
90
|
+
/** Finds a claim type by ID */
|
|
91
|
+
GetClaimTypeByID(id) {
|
|
92
|
+
return this.Base.GetClaimTypeByID(id);
|
|
93
|
+
}
|
|
94
|
+
/** Resolves the concrete BaseIdentityClaimDriver instance for a given claim type */
|
|
95
|
+
GetDriverInstance(claimType) {
|
|
96
|
+
return this.Base.GetDriverInstance(claimType);
|
|
97
|
+
}
|
|
98
|
+
/** Normalizes email address (trimmed, lowercase) */
|
|
99
|
+
NormalizeEmail(email) {
|
|
100
|
+
return this.Base.NormalizeEmail(email);
|
|
101
|
+
}
|
|
102
|
+
/** Parses a claim type's Configuration JSON into the engine-recognized shape */
|
|
103
|
+
GetClaimTypeConfiguration(claimType) {
|
|
104
|
+
return this.Base.GetClaimTypeConfiguration(claimType);
|
|
105
|
+
}
|
|
106
|
+
escapeHtml(str) {
|
|
107
|
+
return str
|
|
108
|
+
.replace(/&/g, '&')
|
|
109
|
+
.replace(/</g, '<')
|
|
110
|
+
.replace(/>/g, '>')
|
|
111
|
+
.replace(/"/g, '"')
|
|
112
|
+
.replace(/'/g, ''');
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Creates and saves an IdentityClaim record, sends an email notification via the MJ Communications
|
|
116
|
+
* framework if configured, and executes the driver's OnCreate lifecycle method.
|
|
117
|
+
*/
|
|
118
|
+
async CreateClaim(params, contextUser, provider) {
|
|
119
|
+
const normalizedEmail = this.NormalizeEmail(params.NormalizedEmail);
|
|
120
|
+
if (!normalizedEmail) {
|
|
121
|
+
throw new Error('NormalizedEmail is required to create an IdentityClaim');
|
|
122
|
+
}
|
|
123
|
+
let claimType;
|
|
124
|
+
if (params.ClaimTypeID) {
|
|
125
|
+
claimType = this.GetClaimTypeByID(params.ClaimTypeID);
|
|
126
|
+
}
|
|
127
|
+
else if (params.ClaimTypeName) {
|
|
128
|
+
claimType = this.GetClaimTypeByName(params.ClaimTypeName);
|
|
129
|
+
}
|
|
130
|
+
if (!claimType) {
|
|
131
|
+
throw new Error(`IdentityClaimType not found for ${params.ClaimTypeName ?? params.ClaimTypeID}`);
|
|
132
|
+
}
|
|
133
|
+
if (!claimType.IsActive) {
|
|
134
|
+
throw new Error(`IdentityClaimType '${claimType.Name}' is inactive and cannot issue new claims`);
|
|
135
|
+
}
|
|
136
|
+
const md = provider ?? this.Provider;
|
|
137
|
+
// 2.2 Accept and normalize EntityID or EntityName
|
|
138
|
+
let resolvedEntityID = null;
|
|
139
|
+
if (params.EntityID) {
|
|
140
|
+
const isGuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(params.EntityID);
|
|
141
|
+
if (isGuid) {
|
|
142
|
+
resolvedEntityID = params.EntityID;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
const matchedEntity = md.Entities.find(e => e.Name.toLowerCase() === params.EntityID?.toLowerCase());
|
|
146
|
+
if (!matchedEntity) {
|
|
147
|
+
throw new Error(`Invalid or unrecognized Entity name/ID: ${params.EntityID}`);
|
|
148
|
+
}
|
|
149
|
+
resolvedEntityID = matchedEntity.ID;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// 3.2 High-entropy token generation & hashing-at-rest
|
|
153
|
+
let rawToken = params.VerificationToken;
|
|
154
|
+
if (!rawToken && !params.MagicLinkInviteID) {
|
|
155
|
+
rawToken = crypto.randomBytes(32).toString('base64url');
|
|
156
|
+
}
|
|
157
|
+
let tokenHash = null;
|
|
158
|
+
if (rawToken) {
|
|
159
|
+
tokenHash = crypto.createHash('sha256').update(rawToken).digest('base64url');
|
|
160
|
+
}
|
|
161
|
+
const metadataObj = params.Metadata ? { ...params.Metadata } : {};
|
|
162
|
+
if (tokenHash) {
|
|
163
|
+
metadataObj.TokenHash = tokenHash;
|
|
164
|
+
}
|
|
165
|
+
const claim = await md.GetEntityObject('MJ: Identity Claims', contextUser);
|
|
166
|
+
claim.NewRecord();
|
|
167
|
+
claim.ClaimTypeID = claimType.ID;
|
|
168
|
+
claim.NormalizedEmail = normalizedEmail;
|
|
169
|
+
claim.EntityID = resolvedEntityID;
|
|
170
|
+
claim.RecordID = params.RecordID ?? null;
|
|
171
|
+
claim.PayloadJSON = params.Payload ? JSON.stringify(params.Payload) : null;
|
|
172
|
+
claim.Status = 'Pending';
|
|
173
|
+
const days = params.ExpiresInDays ?? claimType.DefaultExpirationDays ?? 30;
|
|
174
|
+
const expiresAt = new Date();
|
|
175
|
+
expiresAt.setDate(expiresAt.getDate() + days);
|
|
176
|
+
claim.ExpiresAt = expiresAt;
|
|
177
|
+
claim.MagicLinkInviteID = params.MagicLinkInviteID ?? null;
|
|
178
|
+
claim.MetadataJSON = Object.keys(metadataObj).length > 0 ? JSON.stringify(metadataObj) : null;
|
|
179
|
+
const saved = await claim.Save();
|
|
180
|
+
if (!saved) {
|
|
181
|
+
throw new Error(`Failed to save IdentityClaim: ${claim.LatestResult?.Message ?? 'Unknown error'}`);
|
|
182
|
+
}
|
|
183
|
+
// Send email notification via MJ Communications Framework if enabled
|
|
184
|
+
if (params.SendEmail !== false) {
|
|
185
|
+
try {
|
|
186
|
+
await this.sendClaimEmail(claim, claimType, params, rawToken, contextUser);
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
190
|
+
LogError(`[IdentityClaimEngineServer] Failed to dispatch claim email to ${normalizedEmail}: ${msg}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Invoke driver OnCreate
|
|
194
|
+
const driver = this.GetDriverInstance(claimType);
|
|
195
|
+
if (driver) {
|
|
196
|
+
await driver.OnCreate({ Claim: claim, User: contextUser });
|
|
197
|
+
}
|
|
198
|
+
return claim;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Sends a claimant email notification using CommunicationEngine and TemplateEngineServer
|
|
202
|
+
*/
|
|
203
|
+
async sendClaimEmail(claim, claimType, params, rawToken, contextUser) {
|
|
204
|
+
try {
|
|
205
|
+
const commEngine = CommunicationEngine.Instance;
|
|
206
|
+
await commEngine.Config(false, contextUser);
|
|
207
|
+
const templateEngine = TemplateEngineServer.Instance;
|
|
208
|
+
await templateEngine.Config(false, contextUser);
|
|
209
|
+
const message = new Message();
|
|
210
|
+
message.From = process.env.CLAIM_FROM_EMAIL || process.env.NOTIFICATION_FROM_EMAIL || 'notifications@memberjunction.com';
|
|
211
|
+
message.To = claim.NormalizedEmail;
|
|
212
|
+
// Generate claim / magic link URL with token
|
|
213
|
+
const baseUrl = params.ClaimBaseURL || process.env.PORTAL_BASE_URL || 'https://app.memberjunction.com';
|
|
214
|
+
const tokenParam = rawToken ? `&token=${encodeURIComponent(rawToken)}` : '';
|
|
215
|
+
const claimUrl = `${baseUrl.replace(/\/$/, '')}/claims/redeem?id=${claim.ID}${tokenParam}`;
|
|
216
|
+
message.Subject = params.EmailSubject || `You have a new ${claimType.Name} access claim`;
|
|
217
|
+
// If a template ID is provided or configured on ClaimType, render via template
|
|
218
|
+
const templateId = params.EmailTemplateID;
|
|
219
|
+
const templateEntity = templateId ? templateEngine.Templates.find(t => UUIDsEqual(t.ID, templateId)) : null;
|
|
220
|
+
if (templateEntity) {
|
|
221
|
+
message.HTMLBodyTemplate = templateEntity;
|
|
222
|
+
message.ContextData = {
|
|
223
|
+
Claim: claim,
|
|
224
|
+
ClaimType: claimType,
|
|
225
|
+
ClaimURL: claimUrl,
|
|
226
|
+
RecipientEmail: claim.NormalizedEmail,
|
|
227
|
+
ExpiresAt: claim.ExpiresAt,
|
|
228
|
+
Payload: params.Payload ?? {},
|
|
229
|
+
...(params.TemplateData ?? {})
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
// 3.4 Clean default responsive email body with escaped HTML
|
|
234
|
+
message.Body = `
|
|
235
|
+
<div style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 600px; margin: 0 auto; padding: 24px; color: #1e293b;">
|
|
236
|
+
<h2 style="color: #0f172a; margin-bottom: 16px;">Claim Your ${this.escapeHtml(claimType.Name)}</h2>
|
|
237
|
+
<p style="font-size: 15px; line-height: 1.6; margin-bottom: 24px;">
|
|
238
|
+
An item or entitlement has been issued to <strong>${this.escapeHtml(claim.NormalizedEmail)}</strong>. Click the link below to access or link it to your account:
|
|
239
|
+
</p>
|
|
240
|
+
<div style="margin-bottom: 28px;">
|
|
241
|
+
<a href="${claimUrl}" style="background-color: #0284c7; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600; display: inline-block;">
|
|
242
|
+
View & Redeem Claim
|
|
243
|
+
</a>
|
|
244
|
+
</div>
|
|
245
|
+
<p style="font-size: 13px; color: #64748b;">
|
|
246
|
+
This claim link is valid until ${claim.ExpiresAt.toLocaleDateString()}. If you did not expect this, you can safely ignore this email.
|
|
247
|
+
</p>
|
|
248
|
+
</div>
|
|
249
|
+
`;
|
|
250
|
+
}
|
|
251
|
+
LogStatus(`[IdentityClaimEngineServer] Dispatching claim notification to ${claim.NormalizedEmail}`);
|
|
252
|
+
// 3.5 Make email provider configurable via env
|
|
253
|
+
const commProvider = process.env.CLAIM_EMAIL_PROVIDER || 'SendGrid';
|
|
254
|
+
const sendResult = await commEngine.SendSingleMessage(commProvider, 'Email', message, undefined, false);
|
|
255
|
+
return sendResult?.Success === true;
|
|
256
|
+
}
|
|
257
|
+
catch (err) {
|
|
258
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
259
|
+
LogError(`[IdentityClaimEngineServer] sendClaimEmail error: ${msg}`);
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Fetches all pending, unexpired claims for a normalized email address.
|
|
265
|
+
*/
|
|
266
|
+
async GetPendingClaimsForEmail(email, contextUser, provider) {
|
|
267
|
+
const normalizedEmail = this.NormalizeEmail(email);
|
|
268
|
+
if (!normalizedEmail)
|
|
269
|
+
return [];
|
|
270
|
+
// Reads must come from the same provider as everything else on this call path; a bare
|
|
271
|
+
// `new RunView()` resolves the SEPARATE global RunView provider slot, which the
|
|
272
|
+
// multi-provider compliance scanner does not even cover.
|
|
273
|
+
const rv = new RunView((provider ?? this.Provider));
|
|
274
|
+
const escaped = EscapeSQLString(normalizedEmail);
|
|
275
|
+
// An ISO-8601 literal compares correctly on both SQL Server (DATETIMEOFFSET) and
|
|
276
|
+
// PostgreSQL — GETUTCDATE() would break the PG path the CAS statements already handle.
|
|
277
|
+
const nowUtc = new Date().toISOString();
|
|
278
|
+
const result = await rv.RunView({
|
|
279
|
+
EntityName: 'MJ: Identity Claims',
|
|
280
|
+
ExtraFilter: `NormalizedEmail = '${escaped}' AND Status = 'Pending' AND ExpiresAt > '${nowUtc}'`,
|
|
281
|
+
ResultType: 'entity_object'
|
|
282
|
+
}, contextUser);
|
|
283
|
+
if (result.Success && result.Results) {
|
|
284
|
+
return result.Results;
|
|
285
|
+
}
|
|
286
|
+
return [];
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Redeems a claim for an authenticated user, running the driver's OnClaim implementation.
|
|
290
|
+
*
|
|
291
|
+
* Authorization is email match OR verified token. The email-match path is additionally
|
|
292
|
+
* gated by {@link RedeemClaimOptions.EmailVerified} and the claim type's
|
|
293
|
+
* `Configuration` (`RequireVerifiedEmail` / `RequireToken`) — see {@link RedeemClaimOptions}.
|
|
294
|
+
*/
|
|
295
|
+
async RedeemClaim(claimID, contextUser, provider, token, options) {
|
|
296
|
+
if (!claimID) {
|
|
297
|
+
return { Success: false, ErrorMessage: 'ClaimID is required' };
|
|
298
|
+
}
|
|
299
|
+
if (!contextUser || !contextUser.ID) {
|
|
300
|
+
return { Success: false, ErrorMessage: 'Authenticated User is required to redeem a claim' };
|
|
301
|
+
}
|
|
302
|
+
if (!provider) {
|
|
303
|
+
return { Success: false, ErrorMessage: 'A metadata provider is required to redeem a claim' };
|
|
304
|
+
}
|
|
305
|
+
// `provider` is REQUIRED here, unlike the other methods on this engine, and deliberately
|
|
306
|
+
// so. Redemption reads a claim, reads a magic-link invite, and executes a raw CAS UPDATE —
|
|
307
|
+
// three operations that must all run against the SAME database. Accepting an optional
|
|
308
|
+
// provider would let a caller thread one into the entity reads while the CAS silently fell
|
|
309
|
+
// back to the process global, which is the bug this signature exists to make impossible.
|
|
310
|
+
const md = provider;
|
|
311
|
+
// Read the claim under the system user rather than `contextUser`.
|
|
312
|
+
//
|
|
313
|
+
// Authorization for redemption is enforced below: the caller must either own the
|
|
314
|
+
// claim's email or present a token whose SHA-256 matches the stored hash. That check
|
|
315
|
+
// IS the boundary — the entity read grant was never doing security work here.
|
|
316
|
+
//
|
|
317
|
+
// Loading under `contextUser` also breaks the feature now that UI reads are row-scoped.
|
|
318
|
+
// The row filter is applied to single-record loads, not just RunView (the provider
|
|
319
|
+
// appends GetEffectiveRowFilterWhereClause to the primary-key WHERE), so workflow #3
|
|
320
|
+
// from this entity's migration header — "purchase email differs from the login account
|
|
321
|
+
// email, a verification token confirms ownership" — could never load the very claim it
|
|
322
|
+
// exists to redeem. `contextUser` still drives everything else, including the save.
|
|
323
|
+
// `GetSystemUser()` is typed `UserInfo` but returns undefined when the cache has not been
|
|
324
|
+
// refreshed (see its own doc comment — callers are expected to guard). Fall back to
|
|
325
|
+
// `contextUser` so an unpopulated cache degrades to the previous behaviour rather than
|
|
326
|
+
// passing undefined down into the provider.
|
|
327
|
+
const readUser = UserCache.Instance.GetSystemUser() ?? contextUser;
|
|
328
|
+
const claim = await md.GetEntityObject('MJ: Identity Claims', readUser);
|
|
329
|
+
const loaded = await claim.Load(claimID);
|
|
330
|
+
if (!loaded) {
|
|
331
|
+
return { Success: false, ErrorMessage: `IdentityClaim not found for ID ${claimID}` };
|
|
332
|
+
}
|
|
333
|
+
if (claim.Status !== 'Pending') {
|
|
334
|
+
return { Success: false, ErrorMessage: `Claim is no longer pending (current status: ${claim.Status})` };
|
|
335
|
+
}
|
|
336
|
+
if (new Date(claim.ExpiresAt).getTime() < Date.now()) {
|
|
337
|
+
claim.Status = 'Expired';
|
|
338
|
+
await claim.Save();
|
|
339
|
+
return { Success: false, ErrorMessage: 'Claim has expired' };
|
|
340
|
+
}
|
|
341
|
+
// Claim type is resolved BEFORE the authorization gate so IsActive and the type's
|
|
342
|
+
// Configuration (RequireToken / RequireVerifiedEmail) can participate in it.
|
|
343
|
+
const claimType = this.GetClaimTypeByID(claim.ClaimTypeID);
|
|
344
|
+
if (!claimType) {
|
|
345
|
+
return { Success: false, ErrorMessage: `Claim type ${claim.ClaimTypeID} not found` };
|
|
346
|
+
}
|
|
347
|
+
if (!claimType.IsActive) {
|
|
348
|
+
return { Success: false, ErrorMessage: `Claim type '${claimType.Name}' is inactive; this claim cannot be redeemed` };
|
|
349
|
+
}
|
|
350
|
+
const typeConfig = this.GetClaimTypeConfiguration(claimType);
|
|
351
|
+
// 3.1 & 3.2 Security verification: Email match OR verified bearer token required.
|
|
352
|
+
// Email-match is refused when the IdP explicitly asserted the email as unverified,
|
|
353
|
+
// or when the claim type demands positive verification / a token.
|
|
354
|
+
let userEmailMatch = Boolean(contextUser.Email && this.NormalizeEmail(contextUser.Email) === claim.NormalizedEmail);
|
|
355
|
+
if (userEmailMatch) {
|
|
356
|
+
if (typeConfig.RequireToken === true) {
|
|
357
|
+
userEmailMatch = false; // this type never redeems on email match alone
|
|
358
|
+
}
|
|
359
|
+
else if (options?.EmailVerified === false) {
|
|
360
|
+
userEmailMatch = false; // IdP said the email is unverified — do not trust the match
|
|
361
|
+
}
|
|
362
|
+
else if (typeConfig.RequireVerifiedEmail === true && options?.EmailVerified !== true) {
|
|
363
|
+
userEmailMatch = false; // this type demands a positive IdP assertion
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
let tokenValid = false;
|
|
367
|
+
if (token) {
|
|
368
|
+
const computedHash = crypto.createHash('sha256').update(token).digest('base64url');
|
|
369
|
+
if (claim.MagicLinkInviteID) {
|
|
370
|
+
// Same rationale as the claim read above: this row is being fetched purely to
|
|
371
|
+
// compare its TokenHash against the presented token, which is itself the
|
|
372
|
+
// authorization check. A redeemer whose email differs from the purchase email
|
|
373
|
+
// has no read grant on the invite, and scoping this to them would defeat the
|
|
374
|
+
// token flow rather than protect it.
|
|
375
|
+
const invite = await md.GetEntityObject('MJ: Magic Link Invites', readUser);
|
|
376
|
+
const inviteLoaded = await invite.Load(claim.MagicLinkInviteID);
|
|
377
|
+
if (!inviteLoaded) {
|
|
378
|
+
return { Success: false, ErrorMessage: 'Associated magic link invite could not be verified' };
|
|
379
|
+
}
|
|
380
|
+
if (invite.TokenHash) {
|
|
381
|
+
const expectedBuf = Buffer.from(invite.TokenHash, 'utf8');
|
|
382
|
+
const actualBuf = Buffer.from(computedHash, 'utf8');
|
|
383
|
+
if (expectedBuf.length === actualBuf.length && crypto.timingSafeEqual(expectedBuf, actualBuf)) {
|
|
384
|
+
tokenValid = true;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
else if (claim.MetadataJSON) {
|
|
389
|
+
try {
|
|
390
|
+
const metadata = JSON.parse(claim.MetadataJSON);
|
|
391
|
+
if (metadata && typeof metadata.TokenHash === 'string') {
|
|
392
|
+
const expectedBuf = Buffer.from(metadata.TokenHash, 'utf8');
|
|
393
|
+
const actualBuf = Buffer.from(computedHash, 'utf8');
|
|
394
|
+
if (expectedBuf.length === actualBuf.length && crypto.timingSafeEqual(expectedBuf, actualBuf)) {
|
|
395
|
+
tokenValid = true;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
catch {
|
|
400
|
+
// Ignore metadata parsing error
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
if (!userEmailMatch && !tokenValid) {
|
|
405
|
+
return {
|
|
406
|
+
Success: false,
|
|
407
|
+
ErrorMessage: 'This claim requires either a matching verified email on the signed-in account or the verification token from the claim email'
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
const driver = this.GetDriverInstance(claimType);
|
|
411
|
+
if (!driver) {
|
|
412
|
+
return { Success: false, ErrorMessage: `Claim driver not configured for type ${claimType.Name}` };
|
|
413
|
+
}
|
|
414
|
+
// 3.3 Atomic Compare-And-Swap (CAS) state transition:
|
|
415
|
+
// Sets Status = 'Claimed' iff Status is currently 'Pending' and not expired.
|
|
416
|
+
const casSuccess = await this.consumeClaimAtomic(claim.ID, contextUser.ID, md, contextUser);
|
|
417
|
+
if (!casSuccess) {
|
|
418
|
+
return {
|
|
419
|
+
Success: false,
|
|
420
|
+
ErrorMessage: 'Claim is no longer pending or was concurrently claimed'
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
claim.Status = 'Claimed';
|
|
424
|
+
claim.ClaimedAt = new Date();
|
|
425
|
+
claim.ClaimedByUserID = contextUser.ID;
|
|
426
|
+
const redeemContext = {
|
|
427
|
+
Claim: claim,
|
|
428
|
+
User: contextUser,
|
|
429
|
+
RedemptionToken: token
|
|
430
|
+
};
|
|
431
|
+
let result;
|
|
432
|
+
try {
|
|
433
|
+
result = await driver.OnClaim(redeemContext);
|
|
434
|
+
}
|
|
435
|
+
catch (err) {
|
|
436
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
437
|
+
LogError(`[IdentityClaimEngineServer] driver.OnClaim threw exception for claim ${claim.ID}: ${msg}`);
|
|
438
|
+
result = { Success: false, ErrorMessage: `Claim driver execution failed: ${msg}` };
|
|
439
|
+
}
|
|
440
|
+
// If driver failed, un-consume the claim back to 'Pending' so transient failure doesn't permanently burn the claim
|
|
441
|
+
if (!result.Success) {
|
|
442
|
+
await this.revertClaimAtomic(claim.ID, md, contextUser);
|
|
443
|
+
}
|
|
444
|
+
return result;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Discovers every pending claim addressed to the authenticated user's email and redeems each
|
|
448
|
+
* one. This is workflow #2 from the entity's migration header — "Automatic Claim on Login".
|
|
449
|
+
*
|
|
450
|
+
* Server-only, and deliberately so: it runs through `RedeemClaim`, so each redemption still
|
|
451
|
+
* passes the full gate (email match or verified token, atomic CAS, driver exception handling).
|
|
452
|
+
* The email filter used to find the claims is a lookup convenience, not the security boundary.
|
|
453
|
+
*/
|
|
454
|
+
async AutoClaimForUser(user, provider, options) {
|
|
455
|
+
if (!user || !user.Email)
|
|
456
|
+
return [];
|
|
457
|
+
const claims = await this.GetPendingClaimsForEmail(user.Email, user, provider);
|
|
458
|
+
const results = [];
|
|
459
|
+
for (const claim of claims) {
|
|
460
|
+
// Skip types that opted out of auto-claim or that never redeem on email match alone
|
|
461
|
+
// (RequireToken) — auto-claim has no token to present, so attempting them is noise.
|
|
462
|
+
const claimType = this.GetClaimTypeByID(claim.ClaimTypeID);
|
|
463
|
+
const typeConfig = this.GetClaimTypeConfiguration(claimType);
|
|
464
|
+
if (typeConfig.AutoClaim === false || typeConfig.RequireToken === true) {
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
results.push(await this.RedeemClaim(claim.ID, user, provider, undefined, options));
|
|
468
|
+
}
|
|
469
|
+
return results;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Executes atomic single-use Compare-And-Swap (CAS) state transition on the IdentityClaim record
|
|
473
|
+
* from 'Pending' to 'Claimed'. Returns true iff this execution successfully transitioned the record.
|
|
474
|
+
*/
|
|
475
|
+
async consumeClaimAtomic(claimID, userID, md, contextUser) {
|
|
476
|
+
try {
|
|
477
|
+
// Metadata (schema/table names) and SQL execution MUST come from the same provider.
|
|
478
|
+
// Previously the schema was resolved off `md` while ExecuteSQL was taken from the
|
|
479
|
+
// process global — identical objects in a single-provider process, but the moment a
|
|
480
|
+
// caller threads a provider the statement would be built for one database and run
|
|
481
|
+
// against another.
|
|
482
|
+
const provider = md;
|
|
483
|
+
if (!provider || typeof provider.ExecuteSQL !== 'function') {
|
|
484
|
+
LogError('consumeClaimAtomic: provider or ExecuteSQL not available for atomic CAS');
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
const entityInfo = md.Entities?.find(e => e.Name === 'MJ: Identity Claims');
|
|
488
|
+
const schemaName = entityInfo?.SchemaName ?? '__mj';
|
|
489
|
+
const tableName = entityInfo?.BaseTable ?? 'IdentityClaim';
|
|
490
|
+
const isPg = provider.PlatformKey === 'postgresql';
|
|
491
|
+
const table = isPg ? `${schemaName}.${tableName}` : `[${schemaName}].[${tableName}]`;
|
|
492
|
+
const sql = isPg
|
|
493
|
+
? `UPDATE ${table} SET "Status" = 'Claimed', "ClaimedAt" = (now() AT TIME ZONE 'utc'), "ClaimedByUserID" = $2 WHERE "ID" = $1 AND "Status" = 'Pending' AND ("ExpiresAt" IS NULL OR "ExpiresAt" > (now() AT TIME ZONE 'utc')) RETURNING "ID";`
|
|
494
|
+
: `DECLARE @consumed TABLE (ID UNIQUEIDENTIFIER); UPDATE ${table} SET [Status] = 'Claimed', [ClaimedAt] = SYSUTCDATETIME(), [ClaimedByUserID] = @p1 OUTPUT INSERTED.ID INTO @consumed WHERE [ID] = @p0 AND [Status] = 'Pending' AND ([ExpiresAt] IS NULL OR [ExpiresAt] > SYSUTCDATETIME()); SELECT ID FROM @consumed;`;
|
|
495
|
+
const rows = await provider.ExecuteSQL(sql, [claimID, userID], { isMutation: true }, contextUser);
|
|
496
|
+
return Array.isArray(rows) && rows.length === 1;
|
|
497
|
+
}
|
|
498
|
+
catch {
|
|
499
|
+
return false;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Reverts an atomically consumed claim from 'Claimed' back to 'Pending' if driver execution fails.
|
|
504
|
+
*/
|
|
505
|
+
async revertClaimAtomic(claimID, md, contextUser) {
|
|
506
|
+
try {
|
|
507
|
+
// Same single-provider requirement as consumeClaimAtomic above.
|
|
508
|
+
const provider = md;
|
|
509
|
+
if (!provider || typeof provider.ExecuteSQL !== 'function') {
|
|
510
|
+
return false;
|
|
511
|
+
}
|
|
512
|
+
const entityInfo = md.Entities?.find(e => e.Name === 'MJ: Identity Claims');
|
|
513
|
+
const schemaName = entityInfo?.SchemaName ?? '__mj';
|
|
514
|
+
const tableName = entityInfo?.BaseTable ?? 'IdentityClaim';
|
|
515
|
+
const isPg = provider.PlatformKey === 'postgresql';
|
|
516
|
+
const table = isPg ? `${schemaName}.${tableName}` : `[${schemaName}].[${tableName}]`;
|
|
517
|
+
const sql = isPg
|
|
518
|
+
? `UPDATE ${table} SET "Status" = 'Pending', "ClaimedAt" = NULL, "ClaimedByUserID" = NULL WHERE "ID" = $1 AND "Status" = 'Claimed' RETURNING "ID";`
|
|
519
|
+
: `DECLARE @reverted TABLE (ID UNIQUEIDENTIFIER); UPDATE ${table} SET [Status] = 'Pending', [ClaimedAt] = NULL, [ClaimedByUserID] = NULL OUTPUT INSERTED.ID INTO @reverted WHERE [ID] = @p0 AND [Status] = 'Claimed'; SELECT ID FROM @reverted;`;
|
|
520
|
+
const rows = await provider.ExecuteSQL(sql, [claimID], { isMutation: true }, contextUser);
|
|
521
|
+
return Array.isArray(rows) && rows.length === 1;
|
|
522
|
+
}
|
|
523
|
+
catch (err) {
|
|
524
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
525
|
+
LogError(`[IdentityClaimEngineServer] revertClaimAtomic failed for claim ${claimID}: ${msg}`);
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Revokes a pending claim and invokes the driver's OnRevoke lifecycle method.
|
|
531
|
+
*/
|
|
532
|
+
async RevokeClaim(claimID, contextUser, provider) {
|
|
533
|
+
if (!claimID)
|
|
534
|
+
return;
|
|
535
|
+
const md = provider ?? this.Provider;
|
|
536
|
+
const claim = await md.GetEntityObject('MJ: Identity Claims', contextUser);
|
|
537
|
+
const loaded = await claim.Load(claimID);
|
|
538
|
+
if (!loaded || claim.Status === 'Revoked')
|
|
539
|
+
return;
|
|
540
|
+
claim.Status = 'Revoked';
|
|
541
|
+
const saved = await claim.Save();
|
|
542
|
+
if (!saved) {
|
|
543
|
+
LogError(`[IdentityClaimEngineServer] RevokeClaim failed to save claim ${claimID}: ${claim.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
544
|
+
return; // do not run the driver's OnRevoke against a claim that is still live
|
|
545
|
+
}
|
|
546
|
+
const claimType = this.GetClaimTypeByID(claim.ClaimTypeID);
|
|
547
|
+
if (claimType) {
|
|
548
|
+
const driver = this.GetDriverInstance(claimType);
|
|
549
|
+
if (driver) {
|
|
550
|
+
await driver.OnRevoke({ Claim: claim, User: contextUser });
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
//# sourceMappingURL=IdentityClaimEngineServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IdentityClaimEngineServer.js","sourceRoot":"","sources":["../../src/engines/IdentityClaimEngineServer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAY,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAC9F,OAAO,EAAuC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAY,MAAM,sBAAsB,CAAC;AAC7H,OAAO,EACH,mBAAmB,EAUtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAmCjE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,yBAA0B,SAAQ,aAAwC;IACnF;QACI,KAAK,EAAE,CAAC;QAkBJ,cAAS,GAA6B,IAAI,CAAC;IAjBnD,CAAC;IAEM,MAAM,KAAK,QAAQ;QACtB,OAAO,KAAK,CAAC,WAAW,EAA6B,CAAC;IAC1D,CAAC;IAED,qEAAqE;IACrE,0CAA0C;IAC1C,qEAAqE;IAErE;;OAEG;IACH,IAAc,IAAI;QACd,OAAO,mBAAmB,CAAC,QAAQ,CAAC;IACxC,CAAC;IAID;;;;;;;;;;;;OAYG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,SAAS,IAAK,IAAI,QAAQ,EAAmC,CAAC;IAC9E,CAAC;IACD,IAAW,QAAQ,CAAC,KAAwB;QACxC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,MAAM,CAAC,YAAsB,EAAE,WAAsB,EAAE,QAA4B;QAC5F,IAAI,QAAQ,EAAE,CAAC;YACX,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC9B,CAAC;QACD,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IAChE,CAAC;IAED,sCAAsC;IACtC,IAAW,UAAU;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;IAChC,CAAC;IAED,oDAAoD;IAC7C,kBAAkB,CAAC,IAAY;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED,+BAA+B;IACxB,gBAAgB,CAAC,EAAU;QAC9B,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,oFAAoF;IAC7E,iBAAiB,CAAC,SAAoC;QACzD,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC;IAED,oDAAoD;IAC7C,cAAc,CAAC,KAAa;QAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED,gFAAgF;IACzE,yBAAyB,CAAC,SAAgD;QAC7E,OAAO,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;IAEO,UAAU,CAAC,GAAW;QAC1B,OAAO,GAAG;aACL,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;aACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;aACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;aACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;aACvB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,WAAW,CAAC,MAA+B,EAAE,WAAsB,EAAE,QAA4B;QAC1G,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QACpE,IAAI,CAAC,eAAe,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,SAAgD,CAAC;QACrD,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACrB,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC1D,CAAC;aAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YAC9B,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAC9D,CAAC;QAED,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QACrG,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,CAAC,IAAI,2CAA2C,CAAC,CAAC;QACrG,CAAC;QAED,MAAM,EAAE,GAAG,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;QAErC,kDAAkD;QAClD,IAAI,gBAAgB,GAAkB,IAAI,CAAC;QAC3C,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,iEAAiE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACvG,IAAI,MAAM,EAAE,CAAC;gBACT,gBAAgB,GAAG,MAAM,CAAC,QAAQ,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACJ,MAAM,aAAa,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;gBACrG,IAAI,CAAC,aAAa,EAAE,CAAC;oBACjB,MAAM,IAAI,KAAK,CAAC,2CAA2C,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAClF,CAAC;gBACD,gBAAgB,GAAG,aAAa,CAAC,EAAE,CAAC;YACxC,CAAC;QACL,CAAC;QAED,sDAAsD;QACtD,IAAI,QAAQ,GAAG,MAAM,CAAC,iBAAiB,CAAC;QACxC,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YACzC,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,SAAS,GAAkB,IAAI,CAAC;QACpC,IAAI,QAAQ,EAAE,CAAC;YACX,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACjF,CAAC;QAED,MAAM,WAAW,GAA4B,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3F,IAAI,SAAS,EAAE,CAAC;YACZ,WAAW,CAAC,SAAS,GAAG,SAAS,CAAC;QACtC,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,eAAe,CAAwB,qBAAqB,EAAE,WAAW,CAAC,CAAC;QAClG,KAAK,CAAC,SAAS,EAAE,CAAC;QAClB,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC,EAAE,CAAC;QACjC,KAAK,CAAC,eAAe,GAAG,eAAe,CAAC;QACxC,KAAK,CAAC,QAAQ,GAAG,gBAAgB,CAAC;QAClC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC;QACzC,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3E,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;QAEzB,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC,qBAAqB,IAAI,EAAE,CAAC;QAC3E,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC7B,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QAC9C,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;QAE5B,KAAK,CAAC,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,IAAI,IAAI,CAAC;QAC3D,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE9F,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,CAAC,YAAY,EAAE,OAAO,IAAI,eAAe,EAAE,CAAC,CAAC;QACvG,CAAC;QAED,qEAAqE;QACrE,IAAI,MAAM,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACD,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;YAC/E,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC7D,QAAQ,CAAC,iEAAiE,eAAe,KAAK,GAAG,EAAE,CAAC,CAAC;YACzG,CAAC;QACL,CAAC;QAED,yBAAyB;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,MAAM,EAAE,CAAC;YACT,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QAC/D,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CACxB,KAA4B,EAC5B,SAAoC,EACpC,MAA+B,EAC/B,QAAiB,EACjB,WAAsB;QAEtB,IAAI,CAAC;YACD,MAAM,UAAU,GAAG,mBAAmB,CAAC,QAAQ,CAAC;YAChD,MAAM,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAE5C,MAAM,cAAc,GAAG,oBAAoB,CAAC,QAAQ,CAAC;YACrD,MAAM,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAEhD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,kCAAkC,CAAC;YACzH,OAAO,CAAC,EAAE,GAAG,KAAK,CAAC,eAAe,CAAC;YAEnC,6CAA6C;YAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,gCAAgC,CAAC;YACvG,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,UAAU,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5E,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,qBAAqB,KAAK,CAAC,EAAE,GAAG,UAAU,EAAE,CAAC;YAE3F,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,YAAY,IAAI,kBAAkB,SAAS,CAAC,IAAI,eAAe,CAAC;YAEzF,+EAA+E;YAC/E,MAAM,UAAU,GAAG,MAAM,CAAC,eAAe,CAAC;YAC1C,MAAM,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAE5G,IAAI,cAAc,EAAE,CAAC;gBACjB,OAAO,CAAC,gBAAgB,GAAG,cAAc,CAAC;gBAC1C,OAAO,CAAC,WAAW,GAAG;oBAClB,KAAK,EAAE,KAAK;oBACZ,SAAS,EAAE,SAAS;oBACpB,QAAQ,EAAE,QAAQ;oBAClB,cAAc,EAAE,KAAK,CAAC,eAAe;oBACrC,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;oBAC7B,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;iBACjC,CAAC;YACN,CAAC;iBAAM,CAAC;gBACJ,4DAA4D;gBAC5D,OAAO,CAAC,IAAI,GAAG;;sFAEuD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC;;gFAErC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,eAAe,CAAC;;;uCAG/E,QAAQ;;;;;6DAKc,KAAK,CAAC,SAAS,CAAC,kBAAkB,EAAE;;;iBAGhF,CAAC;YACN,CAAC;YAED,SAAS,CAAC,iEAAiE,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC;YACpG,+CAA+C;YAC/C,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,UAAU,CAAC;YACpE,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,iBAAiB,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YACxG,OAAO,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,QAAQ,CAAC,qDAAqD,GAAG,EAAE,CAAC,CAAC;YACrE,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,wBAAwB,CAAC,KAAa,EAAE,WAAsB,EAAE,QAA4B;QACrG,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,eAAe;YAAE,OAAO,EAAE,CAAC;QAEhC,sFAAsF;QACtF,gFAAgF;QAChF,yDAAyD;QACzD,MAAM,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAgC,CAAC,CAAC;QACnF,MAAM,OAAO,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;QACjD,iFAAiF;QACjF,uFAAuF;QACvF,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAwB;YACnD,UAAU,EAAE,qBAAqB;YACjC,WAAW,EAAE,sBAAsB,OAAO,6CAA6C,MAAM,GAAG;YAChG,UAAU,EAAE,eAAe;SAC9B,EAAE,WAAW,CAAC,CAAC;QAEhB,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnC,OAAO,MAAM,CAAC,OAAO,CAAC;QAC1B,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,WAAqB,EAAE,QAA2B,EAAE,KAAc,EAAE,OAA4B;QACtI,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,CAAC;QACnE,CAAC;QACD,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,kDAAkD,EAAE,CAAC;QAChG,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,mDAAmD,EAAE,CAAC;QACjG,CAAC;QAED,yFAAyF;QACzF,2FAA2F;QAC3F,sFAAsF;QACtF,2FAA2F;QAC3F,yFAAyF;QACzF,MAAM,EAAE,GAAG,QAAQ,CAAC;QACpB,kEAAkE;QAClE,EAAE;QACF,iFAAiF;QACjF,qFAAqF;QACrF,8EAA8E;QAC9E,EAAE;QACF,wFAAwF;QACxF,mFAAmF;QACnF,qFAAqF;QACrF,uFAAuF;QACvF,uFAAuF;QACvF,oFAAoF;QACpF,0FAA0F;QAC1F,oFAAoF;QACpF,uFAAuF;QACvF,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,IAAI,WAAW,CAAC;QACnE,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,eAAe,CAAwB,qBAAqB,EAAE,QAAQ,CAAC,CAAC;QAC/F,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,kCAAkC,OAAO,EAAE,EAAE,CAAC;QACzF,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,+CAA+C,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;QAC5G,CAAC;QAED,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACnD,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;YACzB,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC;QACjE,CAAC;QAED,kFAAkF;QAClF,6EAA6E;QAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC3D,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,cAAc,KAAK,CAAC,WAAW,YAAY,EAAE,CAAC;QACzF,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,eAAe,SAAS,CAAC,IAAI,8CAA8C,EAAE,CAAC;QACzH,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;QAE7D,kFAAkF;QAClF,mFAAmF;QACnF,kEAAkE;QAClE,IAAI,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,eAAe,CAAC,CAAC;QACpH,IAAI,cAAc,EAAE,CAAC;YACjB,IAAI,UAAU,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;gBACnC,cAAc,GAAG,KAAK,CAAC,CAAC,+CAA+C;YAC3E,CAAC;iBAAM,IAAI,OAAO,EAAE,aAAa,KAAK,KAAK,EAAE,CAAC;gBAC1C,cAAc,GAAG,KAAK,CAAC,CAAC,4DAA4D;YACxF,CAAC;iBAAM,IAAI,UAAU,CAAC,oBAAoB,KAAK,IAAI,IAAI,OAAO,EAAE,aAAa,KAAK,IAAI,EAAE,CAAC;gBACrF,cAAc,GAAG,KAAK,CAAC,CAAC,6CAA6C;YACzE,CAAC;QACL,CAAC;QACD,IAAI,UAAU,GAAG,KAAK,CAAC;QAEvB,IAAI,KAAK,EAAE,CAAC;YACR,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAEnF,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;gBAC1B,8EAA8E;gBAC9E,yEAAyE;gBACzE,8EAA8E;gBAC9E,6EAA6E;gBAC7E,qCAAqC;gBACrC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,eAAe,CAA0B,wBAAwB,EAAE,QAAQ,CAAC,CAAC;gBACrG,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBAChE,IAAI,CAAC,YAAY,EAAE,CAAC;oBAChB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,oDAAoD,EAAE,CAAC;gBAClG,CAAC;gBACD,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;oBACnB,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;oBAC1D,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;oBACpD,IAAI,WAAW,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,IAAI,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,CAAC;wBAC5F,UAAU,GAAG,IAAI,CAAC;oBACtB,CAAC;gBACL,CAAC;YACL,CAAC;iBAAM,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBAC5B,IAAI,CAAC;oBACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;oBAChD,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;wBACrD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;wBAC5D,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;wBACpD,IAAI,WAAW,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,IAAI,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,CAAC;4BAC5F,UAAU,GAAG,IAAI,CAAC;wBACtB,CAAC;oBACL,CAAC;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACL,gCAAgC;gBACpC,CAAC;YACL,CAAC;QACL,CAAC;QAED,IAAI,CAAC,cAAc,IAAI,CAAC,UAAU,EAAE,CAAC;YACjC,OAAO;gBACH,OAAO,EAAE,KAAK;gBACd,YAAY,EAAE,8HAA8H;aAC/I,CAAC;QACN,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,wCAAwC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;QACtG,CAAC;QAED,sDAAsD;QACtD,6EAA6E;QAC7E,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QAC5F,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,OAAO;gBACH,OAAO,EAAE,KAAK;gBACd,YAAY,EAAE,wDAAwD;aACzE,CAAC;QACN,CAAC;QAED,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;QACzB,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC7B,KAAK,CAAC,eAAe,GAAG,WAAW,CAAC,EAAE,CAAC;QAEvC,MAAM,aAAa,GAAuB;YACtC,KAAK,EAAE,KAAK;YACZ,IAAI,EAAE,WAAW;YACjB,eAAe,EAAE,KAAK;SACzB,CAAC;QAEF,IAAI,MAAmB,CAAC;QACxB,IAAI,CAAC;YACD,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,QAAQ,CAAC,wEAAwE,KAAK,CAAC,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC;YACrG,MAAM,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,kCAAkC,GAAG,EAAE,EAAE,CAAC;QACvF,CAAC;QAED,mHAAmH;QACnH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,gBAAgB,CAAC,IAAc,EAAE,QAA2B,EAAE,OAA4B;QACnG,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC/E,MAAM,OAAO,GAAkB,EAAE,CAAC;QAClC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,oFAAoF;YACpF,oFAAoF;YACpF,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;YAC7D,IAAI,UAAU,CAAC,SAAS,KAAK,KAAK,IAAI,UAAU,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;gBACrE,SAAS;YACb,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAGD;;;OAGG;IACK,KAAK,CAAC,kBAAkB,CAAC,OAAe,EAAE,MAAc,EAAE,EAAqB,EAAE,WAAsB;QAC3G,IAAI,CAAC;YACD,oFAAoF;YACpF,kFAAkF;YAClF,oFAAoF;YACpF,kFAAkF;YAClF,mBAAmB;YACnB,MAAM,QAAQ,GAAG,EAA0J,CAAC;YAC5K,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;gBACzD,QAAQ,CAAC,yEAAyE,CAAC,CAAC;gBACpF,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,qBAAqB,CAAC,CAAC;YAC5E,MAAM,UAAU,GAAG,UAAU,EAAE,UAAU,IAAI,MAAM,CAAC;YACpD,MAAM,SAAS,GAAG,UAAU,EAAE,SAAS,IAAI,eAAe,CAAC;YAE3D,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,KAAK,YAAY,CAAC;YACnD,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,UAAU,MAAM,SAAS,GAAG,CAAC;YAErF,MAAM,GAAG,GAAG,IAAI;gBACZ,CAAC,CAAC,UAAU,KAAK,4NAA4N;gBAC7O,CAAC,CAAC,yDAAyD,KAAK,uPAAuP,CAAC;YAE5T,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAiB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC;YAClH,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,iBAAiB,CAAC,OAAe,EAAE,EAAqB,EAAE,WAAsB;QAC1F,IAAI,CAAC;YACD,gEAAgE;YAChE,MAAM,QAAQ,GAAG,EAA0J,CAAC;YAC5K,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;gBACzD,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,qBAAqB,CAAC,CAAC;YAC5E,MAAM,UAAU,GAAG,UAAU,EAAE,UAAU,IAAI,MAAM,CAAC;YACpD,MAAM,SAAS,GAAG,UAAU,EAAE,SAAS,IAAI,eAAe,CAAC;YAE3D,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,KAAK,YAAY,CAAC;YACnD,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,UAAU,MAAM,SAAS,GAAG,CAAC;YAErF,MAAM,GAAG,GAAG,IAAI;gBACZ,CAAC,CAAC,UAAU,KAAK,kIAAkI;gBACnJ,CAAC,CAAC,yDAAyD,KAAK,gLAAgL,CAAC;YAErP,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAiB,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC;YAC1G,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,QAAQ,CAAC,kEAAkE,OAAO,KAAK,GAAG,EAAE,CAAC,CAAC;YAC9F,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,WAAsB,EAAE,QAA4B;QAC1F,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,MAAM,EAAE,GAAG,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;QACrC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,eAAe,CAAwB,qBAAqB,EAAE,WAAW,CAAC,CAAC;QAClG,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO;QAElD,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,QAAQ,CAAC,gEAAgE,OAAO,KAAK,KAAK,CAAC,YAAY,EAAE,eAAe,IAAI,eAAe,EAAE,CAAC,CAAC;YAC/I,OAAO,CAAC,sEAAsE;QAClF,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC3D,IAAI,SAAS,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YACjD,IAAI,MAAM,EAAE,CAAC;gBACT,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;YAC/D,CAAC;QACL,CAAC;IACL,CAAC;CACJ"}
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export * from './custom/MJAIBridgeProviderChannelEntityServer.server.js';
|
|
|
31
31
|
export * from './custom/MJAIAgentSessionBridgeEntityServer.server.js';
|
|
32
32
|
export * from './custom/MJAIAgentSessionBridgeParticipantEntityServer.server.js';
|
|
33
33
|
export * from './custom/MJAIRemoteBrowserProviderEntityServer.server.js';
|
|
34
|
+
export * from './custom/MJMaterializedResultEntityServer.server.js';
|
|
34
35
|
export * from './custom/MJAISkillPermissionEntityServer.server.js';
|
|
35
36
|
export * from './custom/MJAISkillEntityServer.server.js';
|
|
36
37
|
export * from './custom/MJMLTrainingPipelineEntityServer.server.js';
|
|
@@ -46,5 +47,6 @@ export * from './custom/util.js';
|
|
|
46
47
|
export * from './engines/QueryEngineServer.js';
|
|
47
48
|
export * from './engines/QueryMatchResult.js';
|
|
48
49
|
export * from './engines/ComponentMetadataEngineServer.js';
|
|
50
|
+
export * from './engines/IdentityClaimEngineServer.js';
|
|
49
51
|
export * from './custom/MJRemoteOperationEntityServer.server.js';
|
|
50
52
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wCAAwC,CAAC;AACvD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,kDAAkD,CAAC;AACjE,cAAc,4DAA4D,CAAC;AAC3E,cAAc,4CAA4C,CAAC;AAC3D,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,wCAAwC,CAAC;AACvD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,uCAAuC,CAAC;AACtD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gDAAgD,CAAC;AAC/D,cAAc,qDAAqD,CAAC;AACpE,cAAc,uDAAuD,CAAC;AACtE,cAAc,oDAAoD,CAAC;AACnE,cAAc,+DAA+D,CAAC;AAC9E,cAAc,uDAAuD,CAAC;AACtE,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,kDAAkD,CAAC;AACjE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mDAAmD,CAAC;AAClE,cAAc,sDAAsD,CAAC;AACrE,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAE9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wCAAwC,CAAC;AACvD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,kDAAkD,CAAC;AACjE,cAAc,4DAA4D,CAAC;AAC3E,cAAc,4CAA4C,CAAC;AAC3D,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,wCAAwC,CAAC;AACvD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,uCAAuC,CAAC;AACtD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gDAAgD,CAAC;AAC/D,cAAc,qDAAqD,CAAC;AACpE,cAAc,uDAAuD,CAAC;AACtE,cAAc,oDAAoD,CAAC;AACnE,cAAc,+DAA+D,CAAC;AAC9E,cAAc,uDAAuD,CAAC;AACtE,cAAc,kDAAkD,CAAC;AACjE,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,kDAAkD,CAAC;AACjE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mDAAmD,CAAC;AAClE,cAAc,sDAAsD,CAAC;AACrE,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAE9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,+CAA+C,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ export * from './custom/MJAIBridgeProviderChannelEntityServer.server.js';
|
|
|
31
31
|
export * from './custom/MJAIAgentSessionBridgeEntityServer.server.js';
|
|
32
32
|
export * from './custom/MJAIAgentSessionBridgeParticipantEntityServer.server.js';
|
|
33
33
|
export * from './custom/MJAIRemoteBrowserProviderEntityServer.server.js';
|
|
34
|
+
export * from './custom/MJMaterializedResultEntityServer.server.js';
|
|
34
35
|
export * from './custom/MJAISkillPermissionEntityServer.server.js';
|
|
35
36
|
export * from './custom/MJAISkillEntityServer.server.js';
|
|
36
37
|
export * from './custom/MJMLTrainingPipelineEntityServer.server.js';
|
|
@@ -46,5 +47,6 @@ export * from './custom/util.js';
|
|
|
46
47
|
export * from './engines/QueryEngineServer.js';
|
|
47
48
|
export * from './engines/QueryMatchResult.js';
|
|
48
49
|
export * from './engines/ComponentMetadataEngineServer.js';
|
|
50
|
+
export * from './engines/IdentityClaimEngineServer.js';
|
|
49
51
|
export * from './custom/MJRemoteOperationEntityServer.server.js';
|
|
50
52
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wCAAwC,CAAC;AACvD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,kDAAkD,CAAC;AACjE,cAAc,4DAA4D,CAAC;AAC3E,cAAc,4CAA4C,CAAC;AAC3D,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,wCAAwC,CAAC;AACvD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,uCAAuC,CAAC;AACtD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gDAAgD,CAAC;AAC/D,cAAc,qDAAqD,CAAC;AACpE,cAAc,uDAAuD,CAAC;AACtE,cAAc,oDAAoD,CAAC;AACnE,cAAc,+DAA+D,CAAC;AAC9E,cAAc,uDAAuD,CAAC;AACtE,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,kDAAkD,CAAC;AACjE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mDAAmD,CAAC;AAClE,cAAc,sDAAsD,CAAC;AACrE,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAE9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wCAAwC,CAAC;AACvD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,kDAAkD,CAAC;AACjE,cAAc,4DAA4D,CAAC;AAC3E,cAAc,4CAA4C,CAAC;AAC3D,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,wCAAwC,CAAC;AACvD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,uCAAuC,CAAC;AACtD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gDAAgD,CAAC;AAC/D,cAAc,qDAAqD,CAAC;AACpE,cAAc,uDAAuD,CAAC;AACtE,cAAc,oDAAoD,CAAC;AACnE,cAAc,+DAA+D,CAAC;AAC9E,cAAc,uDAAuD,CAAC;AACtE,cAAc,kDAAkD,CAAC;AACjE,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,kDAAkD,CAAC;AACjE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mDAAmD,CAAC;AAClE,cAAc,sDAAsD,CAAC;AACrE,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAE9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,+CAA+C,CAAC"}
|