@memberjunction/esignature 0.0.1 → 5.40.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.
@@ -0,0 +1,464 @@
1
+ import { LogError, LogStatus, Metadata, RunView } from '@memberjunction/core';
2
+ import { BaseSingleton, MJGlobal } from '@memberjunction/global';
3
+ import { BaseSignatureProvider } from '../BaseSignatureProvider.js';
4
+ import { SignatureEngineBase } from '../SignatureEngineBase.js';
5
+ import { initializeDriverWithAccountCredentials } from './util.js';
6
+ import { loadArtifactVersionBytes, writeSignedArtifact } from './artifacts.js';
7
+ // ─────────────────────────────────────────────────────────────────────────────
8
+ // Engine
9
+ // ─────────────────────────────────────────────────────────────────────────────
10
+ /**
11
+ * Server-side eSignature engine. Resolves providers via the ClassFactory, decrypts credentials via
12
+ * the Credential Engine, persists the envelope lifecycle across the six `MJ: Signature*` entities,
13
+ * and normalizes inbound webhooks. Wraps {@link SignatureEngineBase} (the metadata cache) using the
14
+ * same containment pattern as FileStorageEngine.
15
+ *
16
+ * Multi-provider rule (CLAUDE.md): every method accepts `contextUser` and an optional
17
+ * `IMetadataProvider`; the global `Metadata.Provider` is used only as an explicit fallback.
18
+ */
19
+ export class SignatureEngine extends BaseSingleton {
20
+ constructor() {
21
+ super(...arguments);
22
+ this._loaded = false;
23
+ this._loading = false;
24
+ this._loadingPromise = null;
25
+ /** Initialized drivers keyed by account ID. */
26
+ this._driverCache = new Map();
27
+ }
28
+ static get Instance() {
29
+ return super.getInstance();
30
+ }
31
+ get Base() {
32
+ return SignatureEngineBase.Instance;
33
+ }
34
+ get Loaded() {
35
+ return this._loaded && this.Base.Loaded;
36
+ }
37
+ get Accounts() {
38
+ return this.Base.Accounts;
39
+ }
40
+ get Providers() {
41
+ return this.Base.Providers;
42
+ }
43
+ // ---- Configuration ----------------------------------------------------------------------------
44
+ /** Load metadata + pre-initialize active drivers. Idempotent unless forceRefresh. */
45
+ async Config(forceRefresh, contextUser, provider) {
46
+ if (this._loaded && !forceRefresh) {
47
+ return;
48
+ }
49
+ if (this._loading && this._loadingPromise) {
50
+ return this._loadingPromise;
51
+ }
52
+ this._loading = true;
53
+ this._loadingPromise = this.innerLoad(forceRefresh, contextUser, provider);
54
+ try {
55
+ await this._loadingPromise;
56
+ }
57
+ finally {
58
+ this._loading = false;
59
+ this._loadingPromise = null;
60
+ }
61
+ }
62
+ async innerLoad(forceRefresh, contextUser, provider) {
63
+ try {
64
+ this._contextUser = contextUser;
65
+ await this.Base.Config(forceRefresh ?? false, contextUser, provider);
66
+ await this.RefreshDriverCache();
67
+ this._loaded = true;
68
+ }
69
+ catch (error) {
70
+ LogError(error);
71
+ throw error;
72
+ }
73
+ }
74
+ /** (Re)initialize drivers for all active accounts. Failures are logged, not thrown. */
75
+ async RefreshDriverCache() {
76
+ this._driverCache.clear();
77
+ const activeAccounts = this.Base.AccountsWithProviders.filter((a) => a.account.IsActive !== false && a.provider.IsActive !== false);
78
+ if (activeAccounts.length === 0 || !this._contextUser) {
79
+ return;
80
+ }
81
+ const contextUser = this._contextUser;
82
+ const results = await Promise.allSettled(activeAccounts.map(async ({ account, provider }) => {
83
+ const driver = await initializeDriverWithAccountCredentials({ accountEntity: account, providerEntity: provider, contextUser });
84
+ this._driverCache.set(account.ID, driver);
85
+ }));
86
+ results.forEach((r, i) => {
87
+ if (r.status === 'rejected') {
88
+ LogError(`SignatureEngine: failed to pre-initialize driver for account "${activeAccounts[i].account.Name}": ${r.reason}`);
89
+ }
90
+ });
91
+ }
92
+ /** Resolve (and cache) an initialized driver for an account. */
93
+ async GetDriver(accountId, contextUser) {
94
+ const cached = this._driverCache.get(accountId);
95
+ if (cached) {
96
+ return cached;
97
+ }
98
+ const resolved = this.Base.GetAccountWithProvider(accountId);
99
+ if (!resolved) {
100
+ throw new Error(`SignatureEngine.GetDriver: account '${accountId}' not found in cached metadata. Did you call Config()?`);
101
+ }
102
+ const driver = await initializeDriverWithAccountCredentials({
103
+ accountEntity: resolved.account,
104
+ providerEntity: resolved.provider,
105
+ contextUser,
106
+ });
107
+ this._driverCache.set(accountId, driver);
108
+ return driver;
109
+ }
110
+ // ---- Send -------------------------------------------------------------------------------------
111
+ /**
112
+ * Create the lifecycle records, send the envelope through the provider, and persist the outcome.
113
+ */
114
+ async SendForSignature(options) {
115
+ const { contextUser } = options;
116
+ const account = this.Base.GetAccountWithProvider(options.signatureAccountId);
117
+ if (!account) {
118
+ return { Success: false, ErrorMessage: `Signature account '${options.signatureAccountId}' not found.` };
119
+ }
120
+ // Resolve documents: prefer caller-supplied bytes; otherwise pull from a referenced Artifact
121
+ // Version (so a document already in MJ — e.g. produced by an agent run — can be sent by
122
+ // reference instead of re-uploading base64).
123
+ const documents = await this.resolveDocuments(options);
124
+ if (!documents.length) {
125
+ return {
126
+ Success: false,
127
+ ErrorMessage: 'No documents supplied. Provide `documents`, or an `artifactVersionId` (or `artifactId`) to send.',
128
+ };
129
+ }
130
+ options = { ...options, documents };
131
+ const request = await this.createRequestRecord(options, account);
132
+ if (!request) {
133
+ return { Success: false, ErrorMessage: 'Failed to create signature request record.' };
134
+ }
135
+ try {
136
+ const driver = await this.GetDriver(options.signatureAccountId, contextUser);
137
+ const result = await driver.CreateEnvelope({
138
+ title: options.title,
139
+ message: options.message,
140
+ documents: options.documents,
141
+ recipients: options.recipients,
142
+ sendImmediately: options.sendImmediately,
143
+ metadata: options.metadata,
144
+ });
145
+ await this.logOperation(request.ID, 'CreateEnvelope', result.Success, 'Draft', result.status ?? null, result.ErrorMessage ?? null, contextUser, options.provider);
146
+ if (!result.Success) {
147
+ return { Success: false, signatureRequestId: request.ID, ErrorMessage: result.ErrorMessage };
148
+ }
149
+ await this.persistSentRequest(request, result.externalEnvelopeId ?? null, result.status, contextUser);
150
+ await this.persistRecipients(request.ID, options.recipients, contextUser, options.provider);
151
+ return {
152
+ Success: true,
153
+ signatureRequestId: request.ID,
154
+ externalEnvelopeId: result.externalEnvelopeId,
155
+ status: request.Status,
156
+ };
157
+ }
158
+ catch (e) {
159
+ const message = e instanceof Error ? e.message : String(e);
160
+ await this.logOperation(request.ID, 'CreateEnvelope', false, 'Draft', null, message, contextUser, options.provider);
161
+ return { Success: false, signatureRequestId: request.ID, ErrorMessage: message };
162
+ }
163
+ }
164
+ // ---- Refresh ----------------------------------------------------------------------------------
165
+ /** Poll the provider for current status and persist it (plus recipient statuses). */
166
+ async RefreshStatus(requestId, contextUser, provider) {
167
+ const request = await this.loadRequest(requestId, contextUser, provider);
168
+ if (!request) {
169
+ return { Success: false, ErrorMessage: `Signature request '${requestId}' not found.` };
170
+ }
171
+ if (!request.ExternalEnvelopeID) {
172
+ return { Success: false, ErrorMessage: 'Signature request has not been sent yet.' };
173
+ }
174
+ const before = request.Status;
175
+ try {
176
+ const driver = await this.GetDriver(request.SignatureAccountID, contextUser);
177
+ const result = await driver.GetEnvelopeStatus(request.ExternalEnvelopeID);
178
+ await this.logOperation(request.ID, 'GetEnvelopeStatus', result.Success, before, result.status ?? null, result.ErrorMessage ?? null, contextUser, provider);
179
+ if (!result.Success) {
180
+ return { Success: false, ErrorMessage: result.ErrorMessage };
181
+ }
182
+ await this.applyStatus(request, result.status, contextUser);
183
+ return { Success: true, status: result.status };
184
+ }
185
+ catch (e) {
186
+ const message = e instanceof Error ? e.message : String(e);
187
+ await this.logOperation(request.ID, 'GetEnvelopeStatus', false, before, null, message, contextUser, provider);
188
+ return { Success: false, ErrorMessage: message };
189
+ }
190
+ }
191
+ // ---- Download ---------------------------------------------------------------------------------
192
+ /** Download the executed document for a completed envelope. */
193
+ async DownloadSigned(requestId, contextUser, provider) {
194
+ const request = await this.loadRequest(requestId, contextUser, provider);
195
+ if (!request) {
196
+ return { Success: false, ErrorMessage: `Signature request '${requestId}' not found.` };
197
+ }
198
+ if (!request.ExternalEnvelopeID) {
199
+ return { Success: false, ErrorMessage: 'Signature request has not been sent yet.' };
200
+ }
201
+ try {
202
+ const driver = await this.GetDriver(request.SignatureAccountID, contextUser);
203
+ const result = await driver.DownloadSignedDocument(request.ExternalEnvelopeID);
204
+ await this.logOperation(request.ID, 'DownloadSignedDocument', result.Success, request.Status, request.Status, result.ErrorMessage ?? null, contextUser, provider);
205
+ if (!result.Success || !result.document) {
206
+ return { Success: false, ErrorMessage: result.ErrorMessage ?? 'Provider returned no document.' };
207
+ }
208
+ await this.recordSignedDocument(request, result.document, contextUser, provider);
209
+ return { Success: true, document: result.document };
210
+ }
211
+ catch (e) {
212
+ const message = e instanceof Error ? e.message : String(e);
213
+ await this.logOperation(request.ID, 'DownloadSignedDocument', false, request.Status, null, message, contextUser, provider);
214
+ return { Success: false, ErrorMessage: message };
215
+ }
216
+ }
217
+ // ---- Void -------------------------------------------------------------------------------------
218
+ /** Void/cancel an in-flight envelope. */
219
+ async Void(requestId, reason, contextUser, provider) {
220
+ const request = await this.loadRequest(requestId, contextUser, provider);
221
+ if (!request) {
222
+ return { Success: false, ErrorMessage: `Signature request '${requestId}' not found.` };
223
+ }
224
+ if (!request.ExternalEnvelopeID) {
225
+ return { Success: false, ErrorMessage: 'Signature request has not been sent yet.' };
226
+ }
227
+ const before = request.Status;
228
+ try {
229
+ const driver = await this.GetDriver(request.SignatureAccountID, contextUser);
230
+ const result = await driver.VoidEnvelope(request.ExternalEnvelopeID, reason);
231
+ await this.logOperation(request.ID, 'VoidEnvelope', result.Success, before, result.Success ? 'Voided' : before, result.ErrorMessage ?? null, contextUser, provider);
232
+ if (!result.Success) {
233
+ return result;
234
+ }
235
+ request.Status = 'Voided';
236
+ request.VoidReason = reason;
237
+ await this.saveOrThrow(request, 'void signature request');
238
+ return { Success: true };
239
+ }
240
+ catch (e) {
241
+ const message = e instanceof Error ? e.message : String(e);
242
+ await this.logOperation(request.ID, 'VoidEnvelope', false, before, null, message, contextUser, provider);
243
+ return { Success: false, ErrorMessage: message };
244
+ }
245
+ }
246
+ // ---- Webhook ----------------------------------------------------------------------------------
247
+ /**
248
+ * Normalize an inbound provider webhook and apply the status — fail-closed on authenticity.
249
+ *
250
+ * Flow (no env vars; HMAC secret lives in the account credential):
251
+ * 1. Parse the payload on a bare driver (parsing needs no secret) to discover the envelope.
252
+ * 2. Find the owning MJ: Signature Request, hence its account.
253
+ * 3. Resolve the account's *credential-initialized* driver and require
254
+ * {@link BaseSignatureProvider.VerifyWebhookSignature} to pass over the raw bytes.
255
+ * 4. Only then apply the status.
256
+ *
257
+ * @param rawBody The exact request bytes, required for byte-accurate HMAC verification.
258
+ */
259
+ async RecordWebhookEvent(driverKey, payload, headers, contextUser, rawBody, provider) {
260
+ const parser = this.resolveDriverByKey(driverKey, contextUser);
261
+ if (!parser) {
262
+ return { Success: false, ErrorMessage: `No signature provider registered for driver key '${driverKey}'.` };
263
+ }
264
+ const event = parser.ParseWebhookEvent(payload, headers);
265
+ if (!event) {
266
+ return { Success: false, ErrorMessage: 'Webhook payload was not handled by the provider.' };
267
+ }
268
+ const request = await this.findRequestByEnvelopeId(event.externalEnvelopeId, contextUser, provider);
269
+ if (!request) {
270
+ await this.logOperation(null, 'Webhook', false, null, event.status, `No request for envelope '${event.externalEnvelopeId}'.`, contextUser, provider);
271
+ return { Success: false, event, ErrorMessage: 'No matching signature request for the webhook envelope.' };
272
+ }
273
+ // Authenticity: verify on the credential-initialized driver for the owning account, under a
274
+ // verify-if-configured policy. A configured-but-invalid signature is rejected; an account
275
+ // with no HMAC secret configured is accepted (logged) so the endpoint works pre-setup.
276
+ const verifier = await this.GetDriver(request.SignatureAccountID, contextUser);
277
+ const verification = verifier.VerifyWebhookSignature(rawBody, headers, payload);
278
+ if (verification === 'Failed') {
279
+ await this.logOperation(request.ID, 'Webhook', false, request.Status, event.status, 'Webhook signature verification failed.', contextUser, provider);
280
+ return { Success: false, event, ErrorMessage: 'Webhook signature verification failed.' };
281
+ }
282
+ if (verification === 'NotConfigured') {
283
+ LogStatus(`[eSignature] Webhook for envelope '${event.externalEnvelopeId}' accepted WITHOUT signature verification ` +
284
+ `(no HMAC key configured on account '${request.SignatureAccountID}'). Configure a webhook secret to enforce authenticity.`);
285
+ }
286
+ const before = request.Status;
287
+ await this.applyStatus(request, event.status, contextUser);
288
+ await this.logOperation(request.ID, 'Webhook', true, before, event.status, JSON.stringify(event), contextUser, provider);
289
+ return { Success: true, event };
290
+ }
291
+ // ─────────────────────────────────────────────────────────────────────────
292
+ // Persistence helpers
293
+ // ─────────────────────────────────────────────────────────────────────────
294
+ /**
295
+ * Resolve the documents to send. Caller-supplied `documents` win; if none are given and an
296
+ * `artifactVersionId` is provided, load that version's bytes from the Artifacts subsystem.
297
+ * (`artifactId` without a version is recorded as provenance only — we don't guess a version.)
298
+ */
299
+ async resolveDocuments(options) {
300
+ if (options.documents?.length) {
301
+ return options.documents;
302
+ }
303
+ if (options.artifactVersionId) {
304
+ const doc = await loadArtifactVersionBytes(options.artifactVersionId, options.contextUser, options.provider);
305
+ return doc ? [doc] : [];
306
+ }
307
+ return [];
308
+ }
309
+ async createRequestRecord(options, account) {
310
+ const md = options.provider ?? Metadata.Provider;
311
+ const request = await md.GetEntityObject('MJ: Signature Requests', options.contextUser);
312
+ request.SignatureAccountID = account.account.ID;
313
+ request.Name = options.title;
314
+ if (options.message != null)
315
+ request.Message = options.message;
316
+ request.Status = 'Draft';
317
+ if (options.entityId != null)
318
+ request.EntityID = options.entityId;
319
+ if (options.recordId != null)
320
+ request.RecordID = options.recordId;
321
+ if (!(await request.Save())) {
322
+ LogError(`SignatureEngine: failed to create request: ${request.LatestResult?.CompleteMessage}`);
323
+ return null;
324
+ }
325
+ await this.persistDocuments(request.ID, options, options.contextUser, options.provider);
326
+ return request;
327
+ }
328
+ async persistDocuments(requestId, options, contextUser, provider) {
329
+ const md = provider ?? Metadata.Provider;
330
+ for (let i = 0; i < options.documents.length; i++) {
331
+ const doc = options.documents[i];
332
+ const row = await md.GetEntityObject('MJ: Signature Request Documents', contextUser);
333
+ row.SignatureRequestID = requestId;
334
+ row.Name = doc.filename;
335
+ row.Sequence = i + 1;
336
+ row.Role = 'Source';
337
+ // Record the Artifact provenance on the first document only (caller-supplied).
338
+ if (i === 0 && options.artifactId != null)
339
+ row.ArtifactID = options.artifactId;
340
+ if (i === 0 && options.artifactVersionId != null)
341
+ row.ArtifactVersionID = options.artifactVersionId;
342
+ await this.saveOrThrow(row, 'create signature request document');
343
+ }
344
+ }
345
+ async persistRecipients(requestId, recipients, contextUser, provider) {
346
+ const md = provider ?? Metadata.Provider;
347
+ for (const r of recipients) {
348
+ const row = await md.GetEntityObject('MJ: Signature Request Recipients', contextUser);
349
+ row.SignatureRequestID = requestId;
350
+ row.Email = r.email;
351
+ if (r.name != null)
352
+ row.Name = r.name;
353
+ row.RoutingOrder = r.routingOrder ?? 1;
354
+ if (r.role != null)
355
+ row.Role = r.role;
356
+ row.Status = 'Sent';
357
+ await this.saveOrThrow(row, 'create signature request recipient');
358
+ }
359
+ }
360
+ async persistSentRequest(request, externalEnvelopeId, status, contextUser) {
361
+ if (externalEnvelopeId)
362
+ request.ExternalEnvelopeID = externalEnvelopeId;
363
+ request.Status = this.persistableStatus(status, 'Sent');
364
+ request.SentAt = new Date();
365
+ await this.saveOrThrow(request, 'persist sent signature request');
366
+ }
367
+ /**
368
+ * Record the executed document: write the bytes back into the Artifacts subsystem (new Artifact
369
+ * + Version) and add a `Role='Signed'` document row linked to that version. If no File Storage
370
+ * Account is configured, fall back to recording the row without an artifact link (the caller
371
+ * still receives the bytes) — a successful download is never lost over missing storage setup.
372
+ */
373
+ async recordSignedDocument(request, document, contextUser, provider) {
374
+ let artifactVersionId;
375
+ try {
376
+ const written = await writeSignedArtifact({
377
+ filename: document.filename,
378
+ bytes: document.bytes,
379
+ contentType: document.contentType,
380
+ title: `${request.Name} (signed)`,
381
+ contextUser,
382
+ provider,
383
+ });
384
+ artifactVersionId = written?.artifactVersionId;
385
+ }
386
+ catch (e) {
387
+ // Artifact write-back is best-effort; log and still record the document row.
388
+ LogError(`SignatureEngine: failed to write signed document to Artifacts: ${e instanceof Error ? e.message : String(e)}`);
389
+ }
390
+ const md = provider ?? Metadata.Provider;
391
+ const row = await md.GetEntityObject('MJ: Signature Request Documents', contextUser);
392
+ row.SignatureRequestID = request.ID;
393
+ row.Name = document.filename;
394
+ row.Sequence = 1;
395
+ row.Role = 'Signed';
396
+ if (artifactVersionId) {
397
+ row.ArtifactVersionID = artifactVersionId;
398
+ }
399
+ await this.saveOrThrow(row, 'record signed document');
400
+ }
401
+ /** Apply a normalized status to a request, stamping CompletedAt on terminal completion. */
402
+ async applyStatus(request, status, contextUser) {
403
+ const persistable = this.persistableStatus(status, request.Status);
404
+ request.Status = persistable;
405
+ if (persistable === 'Completed' && !request.CompletedAt) {
406
+ request.CompletedAt = new Date();
407
+ }
408
+ await this.saveOrThrow(request, 'apply signature status');
409
+ }
410
+ async logOperation(requestId, operation, success, statusBefore, statusAfter, detail, contextUser, provider) {
411
+ try {
412
+ const md = provider ?? Metadata.Provider;
413
+ const log = await md.GetEntityObject('MJ: Signature Request Logs', contextUser);
414
+ if (requestId)
415
+ log.SignatureRequestID = requestId;
416
+ log.Operation = operation;
417
+ log.Success = success;
418
+ if (statusBefore)
419
+ log.StatusBefore = statusBefore;
420
+ if (statusAfter)
421
+ log.StatusAfter = statusAfter;
422
+ if (detail != null)
423
+ log.Detail = detail;
424
+ await log.Save();
425
+ }
426
+ catch (e) {
427
+ // Logging must never break the operation it records.
428
+ LogError(`SignatureEngine: failed to write log for '${operation}': ${e instanceof Error ? e.message : String(e)}`);
429
+ }
430
+ }
431
+ // ─────────────────────────────────────────────────────────────────────────
432
+ // Lookups / small helpers
433
+ // ─────────────────────────────────────────────────────────────────────────
434
+ async loadRequest(requestId, contextUser, provider) {
435
+ const md = provider ?? Metadata.Provider;
436
+ const request = await md.GetEntityObject('MJ: Signature Requests', contextUser);
437
+ const loaded = await request.Load(requestId);
438
+ return loaded ? request : null;
439
+ }
440
+ async findRequestByEnvelopeId(externalEnvelopeId, contextUser, provider) {
441
+ const rv = provider ? RunView.FromMetadataProvider(provider) : new RunView();
442
+ const result = await rv.RunView({
443
+ EntityName: 'MJ: Signature Requests',
444
+ ExtraFilter: `ExternalEnvelopeID = '${externalEnvelopeId.replace(/'/g, "''")}'`,
445
+ ResultType: 'entity_object',
446
+ MaxRows: 1,
447
+ }, contextUser);
448
+ return result.Success && result.Results.length > 0 ? result.Results[0] : null;
449
+ }
450
+ resolveDriverByKey(driverKey, _contextUser) {
451
+ return MJGlobal.Instance.ClassFactory.CreateInstance(BaseSignatureProvider, driverKey) ?? null;
452
+ }
453
+ /** Coerce a normalized status (which may be 'Unknown') into a DB-persistable status. */
454
+ persistableStatus(status, fallback) {
455
+ const candidate = !status || status === 'Unknown' ? fallback : status;
456
+ return candidate === 'Unknown' ? 'Sent' : candidate;
457
+ }
458
+ async saveOrThrow(entity, action) {
459
+ if (!(await entity.Save())) {
460
+ throw new Error(`SignatureEngine: failed to ${action}: ${entity.LatestResult?.CompleteMessage ?? 'unknown error'}`);
461
+ }
462
+ }
463
+ }
464
+ //# sourceMappingURL=SignatureEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignatureEngine.js","sourceRoot":"","sources":["../../src/server/SignatureEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { IMetadataProvider, UserInfo } from '@memberjunction/core';
2
+ import { SignatureDocumentInput } from '../types.js';
3
+ /**
4
+ * Artifact <-> eSignature glue. Two server-side flows:
5
+ * - {@link loadArtifactVersionBytes}: read the bytes of an existing Artifact Version so a caller
6
+ * can send a document already in MJ for signature (instead of re-uploading base64).
7
+ * - {@link writeSignedArtifact}: persist a downloaded, executed PDF back into the Artifacts
8
+ * subsystem as a new Artifact + Version, so the signed document is first-class (agents,
9
+ * viewers, downstream automation can consume it).
10
+ *
11
+ * Both use @memberjunction/storage for the File-mode byte transfer — the same path the file
12
+ * resolvers use — so there's no bespoke storage handling here.
13
+ */
14
+ /** Outcome of writing a signed document back to the Artifacts subsystem. */
15
+ export interface WriteSignedArtifactResult {
16
+ /** New Artifact created to hold the signed document. */
17
+ artifactId: string;
18
+ /** New Artifact Version holding the signed PDF bytes. */
19
+ artifactVersionId: string;
20
+ /** Backing File row. */
21
+ fileId: string;
22
+ }
23
+ /**
24
+ * Resolve the raw bytes of an Artifact Version. Supports both content modes:
25
+ * - `Text` — bytes come from the inline `Content` column.
26
+ * - `File` — bytes are fetched from the backing storage provider via the File's ProviderKey.
27
+ * Returns null if the version can't be loaded or yields no content.
28
+ */
29
+ export declare function loadArtifactVersionBytes(artifactVersionId: string, contextUser: UserInfo, provider?: IMetadataProvider): Promise<SignatureDocumentInput | null>;
30
+ /**
31
+ * Write an executed document back into the Artifacts subsystem as a new Artifact + Version.
32
+ * Returns null (and logs) when no File Storage Account is configured — callers treat this as a
33
+ * soft failure so a successful download is never lost just because artifact storage isn't set up.
34
+ */
35
+ export declare function writeSignedArtifact(options: {
36
+ filename: string;
37
+ bytes: Buffer;
38
+ contentType: string;
39
+ /** Names the new Artifact; defaults to the filename. */
40
+ title?: string;
41
+ contextUser: UserInfo;
42
+ provider?: IMetadataProvider;
43
+ }): Promise<WriteSignedArtifactResult | null>;
44
+ //# sourceMappingURL=artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../src/server/artifacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAuB,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AASxF,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAElD;;;;;;;;;;GAUG;AAEH,4EAA4E;AAC5E,MAAM,WAAW,yBAAyB;IACtC,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC1C,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,QAAQ,EACrB,QAAQ,CAAC,EAAE,iBAAiB,GAC7B,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAuBxC;AAqBD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACrC,OAAO,EAAE;IACL,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAChC,GACF,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAiC3C"}
@@ -0,0 +1,107 @@
1
+ import { LogStatus, Metadata } from '@memberjunction/core';
2
+ import { ArtifactMetadataEngine, MJEnvironmentEntityExtended, } from '@memberjunction/core-entities';
3
+ import { FileStorageEngine } from '@memberjunction/storage';
4
+ /**
5
+ * Resolve the raw bytes of an Artifact Version. Supports both content modes:
6
+ * - `Text` — bytes come from the inline `Content` column.
7
+ * - `File` — bytes are fetched from the backing storage provider via the File's ProviderKey.
8
+ * Returns null if the version can't be loaded or yields no content.
9
+ */
10
+ export async function loadArtifactVersionBytes(artifactVersionId, contextUser, provider) {
11
+ const md = provider ?? Metadata.Provider;
12
+ const version = await md.GetEntityObject('MJ: Artifact Versions', contextUser);
13
+ if (!(await version.Load(artifactVersionId))) {
14
+ return null;
15
+ }
16
+ const filename = version.FileName || version.Name || `${artifactVersionId}.bin`;
17
+ const contentType = version.MimeType || 'application/octet-stream';
18
+ if (version.ContentMode === 'Text') {
19
+ if (version.Content == null) {
20
+ return null;
21
+ }
22
+ return { bytes: Buffer.from(version.Content, 'utf8'), filename, contentType };
23
+ }
24
+ // File mode — pull the bytes from storage.
25
+ if (!version.FileID) {
26
+ return null;
27
+ }
28
+ const bytes = await readFileBytes(version.FileID, contextUser, provider);
29
+ return bytes ? { bytes, filename, contentType } : null;
30
+ }
31
+ /** Read a File row's bytes from its storage provider. Null if the file/account can't be resolved. */
32
+ async function readFileBytes(fileId, contextUser, provider) {
33
+ const md = provider ?? Metadata.Provider;
34
+ const file = await md.GetEntityObject('MJ: Files', contextUser);
35
+ if (!(await file.Load(fileId))) {
36
+ return null;
37
+ }
38
+ await FileStorageEngine.Instance.Config(false, contextUser, provider);
39
+ const accounts = FileStorageEngine.Instance.GetAccountsByProviderID(file.ProviderID);
40
+ if (accounts.length === 0) {
41
+ LogStatus(`[eSignature] No storage account for provider '${file.ProviderID}'; cannot read file '${fileId}'.`);
42
+ return null;
43
+ }
44
+ const driver = await FileStorageEngine.Instance.GetDriver(accounts[0].ID, contextUser);
45
+ return driver.GetObject({ fullPath: file.ProviderKey ?? file.Name });
46
+ }
47
+ /**
48
+ * Write an executed document back into the Artifacts subsystem as a new Artifact + Version.
49
+ * Returns null (and logs) when no File Storage Account is configured — callers treat this as a
50
+ * soft failure so a successful download is never lost just because artifact storage isn't set up.
51
+ */
52
+ export async function writeSignedArtifact(options) {
53
+ const { filename, bytes, contentType, contextUser, provider } = options;
54
+ const md = provider ?? Metadata.Provider;
55
+ await FileStorageEngine.Instance.Config(false, contextUser, provider);
56
+ if (!FileStorageEngine.Instance.ResolveStorageAccount()) {
57
+ LogStatus('[eSignature] No File Storage Account configured; skipping signed-document artifact write-back.');
58
+ return null;
59
+ }
60
+ const upload = await FileStorageEngine.Instance.UploadFile({
61
+ content: bytes,
62
+ fileName: filename,
63
+ mimeType: contentType,
64
+ contextUser,
65
+ provider,
66
+ });
67
+ const artifact = await createArtifact(options.title ?? filename, contentType, filename, contextUser, provider);
68
+ const version = await md.GetEntityObject('MJ: Artifact Versions', contextUser);
69
+ version.ArtifactID = artifact.ID;
70
+ version.VersionNumber = 1;
71
+ version.ContentMode = 'File';
72
+ version.FileID = upload.FileID;
73
+ version.MimeType = contentType;
74
+ version.FileName = filename;
75
+ version.ContentSizeBytes = bytes.length;
76
+ version.UserID = contextUser.ID;
77
+ if (!(await version.Save())) {
78
+ throw new Error(`writeSignedArtifact: failed to save Artifact Version: ${version.LatestResult?.CompleteMessage ?? 'unknown error'}`);
79
+ }
80
+ return { artifactId: artifact.ID, artifactVersionId: version.ID, fileId: upload.FileID };
81
+ }
82
+ /** Create the parent Artifact row, typed from the document MIME (falls back to Generic Binary). */
83
+ async function createArtifact(name, contentType, filename, contextUser, provider) {
84
+ const md = provider ?? Metadata.Provider;
85
+ const artifact = await md.GetEntityObject('MJ: Artifacts', contextUser);
86
+ artifact.Name = name;
87
+ artifact.TypeID = await resolveArtifactTypeId(contentType, filename, contextUser, provider);
88
+ artifact.EnvironmentID = MJEnvironmentEntityExtended.DefaultEnvironmentID;
89
+ artifact.UserID = contextUser.ID;
90
+ if (!(await artifact.Save())) {
91
+ throw new Error(`writeSignedArtifact: failed to save Artifact: ${artifact.LatestResult?.CompleteMessage ?? 'unknown error'}`);
92
+ }
93
+ return artifact;
94
+ }
95
+ /** Resolve an Artifact Type for the document, preferring a MIME match, then a Generic Binary fallback. */
96
+ async function resolveArtifactTypeId(contentType, filename, contextUser, provider) {
97
+ await ArtifactMetadataEngine.Instance.Config(false, contextUser, provider);
98
+ const ext = filename.split('.').pop();
99
+ const byMime = ArtifactMetadataEngine.Instance.GetArtifactTypeByMimeType(contentType, ext);
100
+ const fallback = ArtifactMetadataEngine.Instance.FindArtifactType('Generic Binary');
101
+ const type = byMime ?? fallback;
102
+ if (!type) {
103
+ throw new Error("writeSignedArtifact: no Artifact Type resolved (neither a MIME match nor 'Generic Binary').");
104
+ }
105
+ return type.ID;
106
+ }
107
+ //# sourceMappingURL=artifacts.js.map