antifraud-sdk-core-ts 0.1.2 → 0.1.3
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/CHANGELOG.md +8 -0
- package/README.md +10 -0
- package/dist/document-delivery-controller.d.ts +62 -0
- package/dist/document-delivery-controller.d.ts.map +1 -0
- package/dist/document-delivery-controller.js +77 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.1.3 - 2026-10-18
|
|
6
|
+
|
|
7
|
+
- Consume `antifraud-data-utils-ts@0.1.4` and orchestrate Schema.org
|
|
8
|
+
confidential-document delivery through canonical inline or protected-link
|
|
9
|
+
DIDComm attachments.
|
|
10
|
+
- Preserve trusted sender and recipient bindings, idempotent operation replay,
|
|
11
|
+
exact byte-count agreement and separate delivery, read and signature states.
|
|
12
|
+
|
|
5
13
|
## 0.1.2 - 2026-10-18
|
|
6
14
|
|
|
7
15
|
- Replace binary qualification-issuer lookup with explicit
|
package/README.md
CHANGED
|
@@ -76,6 +76,16 @@ fails before evidence recording. See [Qualification evidence confirmation protot
|
|
|
76
76
|
for attachment, issuer notification, ledger recovery and credential-rendering
|
|
77
77
|
boundaries.
|
|
78
78
|
|
|
79
|
+
## Schema.org document delivery
|
|
80
|
+
|
|
81
|
+
Antifraud documents are Schema.org `DigitalDocument` resources with concrete
|
|
82
|
+
`MediaObject` encodings. They are never FHIR `DocumentReference` resources.
|
|
83
|
+
`createDocumentDeliveryController` consumes the canonical data-utils contract
|
|
84
|
+
and carries governed bytes through DIDComm `attachments[]`, inline or by
|
|
85
|
+
protected reference. Trusted sender, recipient and service bindings remain
|
|
86
|
+
server-owned; replay is operation-idempotent; receipt storage contains no raw
|
|
87
|
+
bytes. Delivery, read and signature remain distinct states.
|
|
88
|
+
|
|
79
89
|
## Dependency direction
|
|
80
90
|
|
|
81
91
|
```text
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { buildSchemaOrgConfidentialDocumentGraph, type DidCommBinaryAttachment, type SchemaOrgDigitalDocumentDescriptor, type SchemaOrgEvidenceMediaAttachment } from 'antifraud-data-utils-ts';
|
|
2
|
+
export type TrustedDocumentDeliveryContext = Readonly<{
|
|
3
|
+
senderReference: string;
|
|
4
|
+
recipientReference: string;
|
|
5
|
+
serviceReference: string;
|
|
6
|
+
}>;
|
|
7
|
+
export type DocumentDeliveryAttachmentInput = Readonly<{
|
|
8
|
+
kind: 'inline';
|
|
9
|
+
mediaObject: SchemaOrgEvidenceMediaAttachment;
|
|
10
|
+
bytes: Uint8Array;
|
|
11
|
+
}> | Readonly<{
|
|
12
|
+
kind: 'linked';
|
|
13
|
+
mediaObject: SchemaOrgEvidenceMediaAttachment;
|
|
14
|
+
}>;
|
|
15
|
+
export type DocumentDeliveryRequest = Readonly<{
|
|
16
|
+
operationId: string;
|
|
17
|
+
messageId: string;
|
|
18
|
+
trustedContext: TrustedDocumentDeliveryContext;
|
|
19
|
+
manifest: SchemaOrgDigitalDocumentDescriptor;
|
|
20
|
+
document: SchemaOrgDigitalDocumentDescriptor;
|
|
21
|
+
attachment: DocumentDeliveryAttachmentInput;
|
|
22
|
+
}>;
|
|
23
|
+
export type PreparedDocumentDelivery = Readonly<{
|
|
24
|
+
operationId: string;
|
|
25
|
+
messageId: string;
|
|
26
|
+
trustedContext: TrustedDocumentDeliveryContext;
|
|
27
|
+
documentGraph: ReturnType<typeof buildSchemaOrgConfidentialDocumentGraph>;
|
|
28
|
+
attachments: readonly [DidCommBinaryAttachment];
|
|
29
|
+
}>;
|
|
30
|
+
export type DocumentDeliveryReceipt = Readonly<{
|
|
31
|
+
operationId: string;
|
|
32
|
+
messageId: string;
|
|
33
|
+
deliveryReference: string;
|
|
34
|
+
deliveredAt: string;
|
|
35
|
+
deliveryStatus: 'delivered';
|
|
36
|
+
readStatus: 'unread';
|
|
37
|
+
signatureStatus: 'unsigned';
|
|
38
|
+
}>;
|
|
39
|
+
type DocumentDeliveryContinuity = Readonly<{
|
|
40
|
+
messageId: string;
|
|
41
|
+
senderReference: string;
|
|
42
|
+
recipientReference: string;
|
|
43
|
+
contentId: string;
|
|
44
|
+
receipt: DocumentDeliveryReceipt;
|
|
45
|
+
}>;
|
|
46
|
+
export type DocumentDeliveryControllerPorts = Readonly<{
|
|
47
|
+
transport: Readonly<{
|
|
48
|
+
send(delivery: PreparedDocumentDelivery): Promise<Readonly<{
|
|
49
|
+
deliveryReference: string;
|
|
50
|
+
deliveredAt: string;
|
|
51
|
+
}>>;
|
|
52
|
+
}>;
|
|
53
|
+
receipts: Readonly<{
|
|
54
|
+
get(operationId: string): Promise<DocumentDeliveryContinuity | undefined>;
|
|
55
|
+
put(operationId: string, record: DocumentDeliveryContinuity): Promise<void>;
|
|
56
|
+
}>;
|
|
57
|
+
}>;
|
|
58
|
+
export declare function createDocumentDeliveryController(ports: DocumentDeliveryControllerPorts): Readonly<{
|
|
59
|
+
deliver(request: DocumentDeliveryRequest): Promise<DocumentDeliveryReceipt>;
|
|
60
|
+
}>;
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=document-delivery-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-delivery-controller.d.ts","sourceRoot":"","sources":["../src/document-delivery-controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,uCAAuC,EACvC,KAAK,uBAAuB,EAC5B,KAAK,kCAAkC,EACvC,KAAK,gCAAgC,EACtC,MAAM,yBAAyB,CAAA;AAEhC,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC;IACpD,eAAe,EAAE,MAAM,CAAA;IACvB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,gBAAgB,EAAE,MAAM,CAAA;CACzB,CAAC,CAAA;AAEF,MAAM,MAAM,+BAA+B,GACvC,QAAQ,CAAC;IACP,IAAI,EAAE,QAAQ,CAAA;IACd,WAAW,EAAE,gCAAgC,CAAA;IAC7C,KAAK,EAAE,UAAU,CAAA;CAClB,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,QAAQ,CAAA;IACd,WAAW,EAAE,gCAAgC,CAAA;CAC9C,CAAC,CAAA;AAEN,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,8BAA8B,CAAA;IAC9C,QAAQ,EAAE,kCAAkC,CAAA;IAC5C,QAAQ,EAAE,kCAAkC,CAAA;IAC5C,UAAU,EAAE,+BAA+B,CAAA;CAC5C,CAAC,CAAA;AAEF,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,8BAA8B,CAAA;IAC9C,aAAa,EAAE,UAAU,CAAC,OAAO,uCAAuC,CAAC,CAAA;IACzE,WAAW,EAAE,SAAS,CAAC,uBAAuB,CAAC,CAAA;CAChD,CAAC,CAAA;AAEF,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,iBAAiB,EAAE,MAAM,CAAA;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,WAAW,CAAA;IAC3B,UAAU,EAAE,QAAQ,CAAA;IACpB,eAAe,EAAE,UAAU,CAAA;CAC5B,CAAC,CAAA;AAEF,KAAK,0BAA0B,GAAG,QAAQ,CAAC;IACzC,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,MAAM,CAAA;IACvB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,uBAAuB,CAAA;CACjC,CAAC,CAAA;AAEF,MAAM,MAAM,+BAA+B,GAAG,QAAQ,CAAC;IACrD,SAAS,EAAE,QAAQ,CAAC;QAClB,IAAI,CAAC,QAAQ,EAAE,wBAAwB,GAAG,OAAO,CAAC,QAAQ,CAAC;YACzD,iBAAiB,EAAE,MAAM,CAAA;YACzB,WAAW,EAAE,MAAM,CAAA;SACpB,CAAC,CAAC,CAAA;KACJ,CAAC,CAAA;IACF,QAAQ,EAAE,QAAQ,CAAC;QACjB,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC,CAAA;QACzE,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAC5E,CAAC,CAAA;CACH,CAAC,CAAA;AAqDF,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,+BAA+B;qBAE5D,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC;GA+BpF"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
+
import { buildDidCommInlineBinaryAttachment, buildDidCommLinkedBinaryAttachment, buildSchemaOrgConfidentialDocumentGraph, } from 'antifraud-data-utils-ts';
|
|
3
|
+
function requireNonEmpty(value, path) {
|
|
4
|
+
const normalized = value.trim();
|
|
5
|
+
if (!normalized)
|
|
6
|
+
throw new TypeError(`${path} must not be empty`);
|
|
7
|
+
return normalized;
|
|
8
|
+
}
|
|
9
|
+
function prepareDocumentDelivery(request) {
|
|
10
|
+
const operationId = requireNonEmpty(request.operationId, 'operationId');
|
|
11
|
+
const messageId = requireNonEmpty(request.messageId, 'messageId');
|
|
12
|
+
const trustedContext = Object.freeze({
|
|
13
|
+
senderReference: requireNonEmpty(request.trustedContext.senderReference, 'senderReference'),
|
|
14
|
+
recipientReference: requireNonEmpty(request.trustedContext.recipientReference, 'recipientReference'),
|
|
15
|
+
serviceReference: requireNonEmpty(request.trustedContext.serviceReference, 'serviceReference'),
|
|
16
|
+
});
|
|
17
|
+
const documentGraph = buildSchemaOrgConfidentialDocumentGraph({
|
|
18
|
+
manifest: request.manifest,
|
|
19
|
+
documents: [{ ...request.document, attachment: request.attachment.mediaObject }],
|
|
20
|
+
});
|
|
21
|
+
const attachment = request.attachment.kind === 'inline'
|
|
22
|
+
? buildDidCommInlineBinaryAttachment({
|
|
23
|
+
id: request.attachment.mediaObject.id,
|
|
24
|
+
mediaType: request.attachment.mediaObject.mediaType,
|
|
25
|
+
bytes: request.attachment.bytes,
|
|
26
|
+
})
|
|
27
|
+
: buildDidCommLinkedBinaryAttachment(request.attachment.mediaObject);
|
|
28
|
+
if (attachment.byte_count !== request.attachment.mediaObject.contentSize) {
|
|
29
|
+
throw new TypeError('DIDComm attachment byte count does not match the Schema.org MediaObject');
|
|
30
|
+
}
|
|
31
|
+
return Object.freeze({
|
|
32
|
+
operationId,
|
|
33
|
+
messageId,
|
|
34
|
+
trustedContext,
|
|
35
|
+
documentGraph,
|
|
36
|
+
attachments: Object.freeze([attachment]),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function isSameOperation(current, prepared, contentId) {
|
|
40
|
+
return current.messageId === prepared.messageId
|
|
41
|
+
&& current.senderReference === prepared.trustedContext.senderReference
|
|
42
|
+
&& current.recipientReference === prepared.trustedContext.recipientReference
|
|
43
|
+
&& current.contentId === contentId;
|
|
44
|
+
}
|
|
45
|
+
export function createDocumentDeliveryController(ports) {
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
async deliver(request) {
|
|
48
|
+
const prepared = prepareDocumentDelivery(request);
|
|
49
|
+
const contentId = request.attachment.mediaObject.contentId;
|
|
50
|
+
const current = await ports.receipts.get(prepared.operationId);
|
|
51
|
+
if (current) {
|
|
52
|
+
if (!isSameOperation(current, prepared, contentId)) {
|
|
53
|
+
throw new Error('Document delivery operation replay does not match the original request');
|
|
54
|
+
}
|
|
55
|
+
return current.receipt;
|
|
56
|
+
}
|
|
57
|
+
const delivered = await ports.transport.send(prepared);
|
|
58
|
+
const receipt = Object.freeze({
|
|
59
|
+
operationId: prepared.operationId,
|
|
60
|
+
messageId: prepared.messageId,
|
|
61
|
+
deliveryReference: requireNonEmpty(delivered.deliveryReference, 'deliveryReference'),
|
|
62
|
+
deliveredAt: requireNonEmpty(delivered.deliveredAt, 'deliveredAt'),
|
|
63
|
+
deliveryStatus: 'delivered',
|
|
64
|
+
readStatus: 'unread',
|
|
65
|
+
signatureStatus: 'unsigned',
|
|
66
|
+
});
|
|
67
|
+
await ports.receipts.put(prepared.operationId, Object.freeze({
|
|
68
|
+
messageId: prepared.messageId,
|
|
69
|
+
senderReference: prepared.trustedContext.senderReference,
|
|
70
|
+
recipientReference: prepared.trustedContext.recipientReference,
|
|
71
|
+
contentId,
|
|
72
|
+
receipt,
|
|
73
|
+
}));
|
|
74
|
+
return receipt;
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './openid4vp.js';
|
|
2
2
|
export * from './credential-issuance-controller.js';
|
|
3
|
+
export * from './document-delivery-controller.js';
|
|
3
4
|
export * from './presentation-controller.js';
|
|
4
5
|
export * from './presentation-session.js';
|
|
5
6
|
export * from './qualification-evidence-controller.js';
|
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,gBAAgB,CAAA;AAC9B,cAAc,qCAAqC,CAAA;AACnD,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA;AACzC,cAAc,wCAAwC,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qCAAqC,CAAA;AACnD,cAAc,mCAAmC,CAAA;AACjD,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA;AACzC,cAAc,wCAAwC,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './openid4vp.js';
|
|
2
2
|
export * from './credential-issuance-controller.js';
|
|
3
|
+
export * from './document-delivery-controller.js';
|
|
3
4
|
export * from './presentation-controller.js';
|
|
4
5
|
export * from './presentation-session.js';
|
|
5
6
|
export * from './qualification-evidence-controller.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "antifraud-sdk-core-ts",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Runtime-neutral orchestration for identity verification and provider-issued credentials",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -34,6 +34,6 @@
|
|
|
34
34
|
"typescript": "^5.9.3"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"antifraud-data-utils-ts": "0.1.
|
|
37
|
+
"antifraud-data-utils-ts": "0.1.4"
|
|
38
38
|
}
|
|
39
39
|
}
|