Files
archy/apps/did-wallet/node_modules/@tbd54566975/dwn-sdk-js/src/handlers/protocols-configure.ts
T
Dorian 0d073fa89e Add comprehensive installation and setup documentation
- Add GETTING_STARTED.md with quick start guide and development modes
- Add INSTALL.sh automated installation script
- Add INSTALLATION_CHECKLIST.md, INSTALLATION_SUCCESS.md, and INSTALLATION_SUMMARY.md
- Add QUICK_REFERENCE.md for common commands
- Add SETUP_GUIDE.md with detailed setup instructions
- Update README.md with improved project overview
- Add did-wallet app dependencies and node_modules
2026-01-27 17:18:21 +00:00

112 lines
4.0 KiB
TypeScript

import type { DidResolver } from '@web5/dids';
import type { EventLog } from '../types/event-log.js';
import type { EventStream } from '../types/subscriptions.js';
import type { GenericMessageReply } from '../types/message-types.js';
import type { MessageStore } from '../types//message-store.js';
import type { MethodHandler } from '../types/method-handler.js';
import type { ProtocolsConfigureMessage } from '../types/protocols-types.js';
import { Message } from '../core/message.js';
import { messageReplyFromError } from '../core/message-reply.js';
import { ProtocolsConfigure } from '../interfaces/protocols-configure.js';
import { authenticate, authorizeOwner } from '../core/auth.js';
import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
export class ProtocolsConfigureHandler implements MethodHandler {
constructor(
private didResolver: DidResolver,
private messageStore: MessageStore,
private eventLog: EventLog,
private eventStream?: EventStream
) { }
public async handle({
tenant,
message,
}: {tenant: string, message: ProtocolsConfigureMessage }): Promise<GenericMessageReply> {
let protocolsConfigure: ProtocolsConfigure;
try {
protocolsConfigure = await ProtocolsConfigure.parse(message);
} catch (e) {
return messageReplyFromError(e, 400);
}
// authentication & authorization
try {
await authenticate(message.authorization, this.didResolver);
await authorizeOwner(tenant, protocolsConfigure);
} catch (e) {
return messageReplyFromError(e, 401);
}
// attempt to get existing protocol
const query = {
interface : DwnInterfaceName.Protocols,
method : DwnMethodName.Configure,
protocol : message.descriptor.definition.protocol
};
const { messages: existingMessages } = await this.messageStore.query(tenant, [ query ]);
// find newest message, and if the incoming message is the newest
let newestMessage = await Message.getNewestMessage(existingMessages);
let incomingMessageIsNewest = false;
if (newestMessage === undefined || await Message.isNewer(message, newestMessage)) {
incomingMessageIsNewest = true;
newestMessage = message;
}
// write the incoming message to DB if incoming message is newest
let messageReply: GenericMessageReply;
if (incomingMessageIsNewest) {
const indexes = ProtocolsConfigureHandler.constructIndexes(protocolsConfigure);
await this.messageStore.put(tenant, message, indexes);
const messageCid = await Message.getCid(message);
await this.eventLog.append(tenant, messageCid, indexes);
// only emit if the event stream is set
if (this.eventStream !== undefined) {
this.eventStream.emit(tenant, { message }, indexes);
}
messageReply = {
status: { code: 202, detail: 'Accepted' }
};
} else {
messageReply = {
status: { code: 409, detail: 'Conflict' }
};
}
// delete all existing records that are smaller
const deletedMessageCids: string[] = [];
for (const message of existingMessages) {
if (await Message.isNewer(newestMessage, message)) {
const messageCid = await Message.getCid(message);
deletedMessageCids.push(messageCid);
await this.messageStore.delete(tenant, messageCid);
}
}
await this.eventLog.deleteEventsByCid(tenant, deletedMessageCids);
return messageReply;
};
static constructIndexes(protocolsConfigure: ProtocolsConfigure): { [key: string]: string | boolean } {
// strip out `definition` as it is not indexable
const { definition, ...propertiesToIndex } = protocolsConfigure.message.descriptor;
const { author } = protocolsConfigure;
const indexes: { [key: string]: string | boolean } = {
...propertiesToIndex,
author : author!,
protocol : definition.protocol, // retain protocol url from `definition`,
published : definition.published // retain published state from definition
};
return indexes;
}
}