@veramo/did-comm
Version:
Veramo messaging plugin implementing DIDComm v2.
130 lines • 5.04 kB
JavaScript
import { v4 as uuidv4 } from 'uuid';
import { fetch } from 'cross-fetch';
import { decodeBase64url } from '@veramo/utils';
import Debug from 'debug';
const debug = Debug('veramo:did-comm:http-transport');
/**
* Abstract implementation of {@link IDIDCommTransport}.
*
* @beta This API may change without a BREAKING CHANGE notice.
*/
export class AbstractDIDCommTransport {
id;
/**
* Shared constructor that takes an optional identifier (for reusing) for
* this {@link IDIDCommTransport}.
*
* @param id - An optional identifier for this {@link IDIDCommTransport}.
*
* @beta This API may change without a BREAKING CHANGE notice.
*/
constructor(id) {
this.id = id || uuidv4();
}
}
/**
* Implementation of {@link IDIDCommTransport} to provide a simple
* transport based on HTTP(S) requests.
*
* @beta This API may change without a BREAKING CHANGE notice.
*/
export class DIDCommHttpTransport extends AbstractDIDCommTransport {
/**
* Defines the default HTTP method to use if not specified
* in the DID Document service entry of the recipient.
*/
httpMethod;
/**
* Creates a new {@link DIDCommHttpTransport}.
* @param httpMethod - Default HTTP method if not specified in the service
* section.
*/
constructor(httpMethod) {
super();
this.httpMethod = httpMethod || 'post';
}
/** {@inheritdoc AbstractDIDCommTransport.isServiceSupported} */
isServiceSupported(service) {
// serviceEndpoint can be a string, a ServiceEndpoint object, or an array of strings or ServiceEndpoint objects
return ((typeof service.serviceEndpoint === 'string' &&
(service.serviceEndpoint.startsWith('http://') || service.serviceEndpoint.startsWith('https://'))) ||
(service.serviceEndpoint.uri &&
typeof service.serviceEndpoint.uri === 'string' &&
(service.serviceEndpoint.uri.startsWith('http://') ||
service.serviceEndpoint.uri.startsWith('https://'))) ||
(service.serviceEndpoint.length > 0 &&
typeof service.serviceEndpoint[0] === 'string' &&
(service.serviceEndpoint[0].startsWith('http://') ||
service.serviceEndpoint[0].startsWith('https://'))) ||
(service.serviceEndpoint.length > 0 &&
typeof service.serviceEndpoint[0].uri === 'string' &&
(service.serviceEndpoint[0].uri.startsWith('http://') ||
service.serviceEndpoint[0].uri.startsWith('https://'))));
}
/** {@inheritdoc AbstractDIDCommTransport.send} */
async send(service, message) {
let serviceEndpointUrl = '';
if (typeof service.serviceEndpoint === 'string') {
serviceEndpointUrl = service.serviceEndpoint;
}
else if (service.serviceEndpoint.uri) {
serviceEndpointUrl = service.serviceEndpoint.uri;
}
else if (service.serviceEndpoint.length > 0) {
if (typeof service.serviceEndpoint[0] === 'string') {
serviceEndpointUrl = service.serviceEndpoint[0];
}
else if (service.serviceEndpoint[0].uri) {
serviceEndpointUrl = service.serviceEndpoint[0].uri;
}
}
try {
const contentType = this.inferContentType(message);
debug(`Sending message to ${serviceEndpointUrl}`);
const response = await fetch(serviceEndpointUrl, {
method: this.httpMethod,
body: message,
headers: {
'content-type': contentType,
},
});
let result;
debug(`Response: ${JSON.stringify(response)}`);
if (response.ok) {
let returnMessage;
// Check if response is a DIDComm message
if (response.headers.get('Content-Type')?.startsWith('application/didcomm')) {
returnMessage = await response.json();
}
result = {
result: 'successfully sent message: ' + response.statusText,
returnMessage: returnMessage,
};
}
else {
result = {
error: 'failed to send message: ' + response.statusText,
};
}
return result;
}
catch (e) {
return {
error: 'failed to send message: ' + e,
};
}
}
inferContentType(message) {
try {
const parsedMessage = JSON.parse(message);
const contentType = parsedMessage?.typ ??
JSON.parse(decodeBase64url(parsedMessage.protected ?? '{}'))?.typ ??
'application/json';
return contentType;
}
catch (e) {
return 'application/json';
}
}
}
//# sourceMappingURL=transports.js.map