diff --git a/README.md b/README.md index 1c5838966..9168e3c2f 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,8 @@ Here's to a thrilling Hacktoberfest voyage with us! 🎉 # Decentralized Web Node (DWN) SDK Code Coverage -![Statements](https://img.shields.io/badge/statements-96.8%25-brightgreen.svg?style=flat) ![Branches](https://img.shields.io/badge/branches-93.94%25-brightgreen.svg?style=flat) ![Functions](https://img.shields.io/badge/functions-93.4%25-brightgreen.svg?style=flat) ![Lines](https://img.shields.io/badge/lines-96.8%25-brightgreen.svg?style=flat) + +![Statements](https://img.shields.io/badge/statements-97.77%25-brightgreen.svg?style=flat) ![Branches](https://img.shields.io/badge/branches-95.03%25-brightgreen.svg?style=flat) ![Functions](https://img.shields.io/badge/functions-94.26%25-brightgreen.svg?style=flat) ![Lines](https://img.shields.io/badge/lines-97.77%25-brightgreen.svg?style=flat) - [Introduction](#introduction) - [Installation](#installation) diff --git a/build/compile-validators.js b/build/compile-validators.js index 0d1381ddf..968396330 100644 --- a/build/compile-validators.js +++ b/build/compile-validators.js @@ -17,6 +17,7 @@ import Ajv from 'ajv'; import mkdirp from 'mkdirp'; import standaloneCode from 'ajv/dist/standalone/index.js'; +import Authorization from '../json-schemas/authorization.json' assert { type: 'json' }; import BaseAuthorizationPayload from '../json-schemas/authorization-payloads/base-authorization-payload.json' assert { type: 'json' }; import Definitions from '../json-schemas/definitions.json' assert { type: 'json' }; import EventsGet from '../json-schemas/events/events-get.json' assert { type: 'json' }; @@ -40,12 +41,13 @@ import RecordsFilter from '../json-schemas/interface-methods/records-filter.json import RecordsQuery from '../json-schemas/interface-methods/records-query.json' assert { type: 'json' }; import RecordsRead from '../json-schemas/interface-methods/records-read.json' assert { type: 'json' }; import RecordsWrite from '../json-schemas/interface-methods/records-write.json' assert { type: 'json' }; -import RecordsWriteAuthorizationPayload from '../json-schemas/authorization-payloads/records-write-authorization-payload.json' assert { type: 'json' }; +import RecordsWriteAuthorSignaturePayload from '../json-schemas/authorization-payloads/records-write-authorization-payload.json' assert { type: 'json' }; import RecordsWriteUnidentified from '../json-schemas/interface-methods/records-write-unidentified.json' assert { type: 'json' }; import SnapshotsCreate from '../json-schemas/interface-methods/snapshots-create.json' assert { type: 'json' }; import SubscriptionsRequest from '../json-schemas/interface-methods/subscriptions-request.json' assert { type: 'json' }; const schemas = { + Authorization, RecordsDelete, RecordsQuery, RecordsWrite, @@ -72,7 +74,7 @@ const schemas = { PublicJwk, SnapshotsCreate, BaseAuthorizationPayload, - RecordsWriteAuthorizationPayload + RecordsWriteAuthorSignaturePayload }; const ajv = new Ajv({ code: { source: true, esm: true } }); diff --git a/json-schemas/authorization.json b/json-schemas/authorization.json new file mode 100644 index 000000000..20cde3a81 --- /dev/null +++ b/json-schemas/authorization.json @@ -0,0 +1,11 @@ +{ + "$id": "https://identity.foundation/dwn/json-schemas/authorization.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "properties": { + "author": { + "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + } + } +} \ No newline at end of file diff --git a/json-schemas/events/events-get.json b/json-schemas/events/events-get.json index 93429eff1..a79b67aaa 100644 --- a/json-schemas/events/events-get.json +++ b/json-schemas/events/events-get.json @@ -9,7 +9,7 @@ ], "properties": { "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "descriptor": { "type": "object", diff --git a/json-schemas/hooks/hooks-write.json b/json-schemas/hooks/hooks-write.json index ac8e21510..990b57186 100644 --- a/json-schemas/hooks/hooks-write.json +++ b/json-schemas/hooks/hooks-write.json @@ -9,7 +9,7 @@ ], "properties": { "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "descriptor": { "type": "object", diff --git a/json-schemas/interface-methods/messages-get.json b/json-schemas/interface-methods/messages-get.json index 3126ff507..da1c3d962 100644 --- a/json-schemas/interface-methods/messages-get.json +++ b/json-schemas/interface-methods/messages-get.json @@ -9,7 +9,7 @@ ], "properties": { "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "descriptor": { "type": "object", diff --git a/json-schemas/interface-methods/permissions-grant.json b/json-schemas/interface-methods/permissions-grant.json index da6dde5f8..548fe9544 100644 --- a/json-schemas/interface-methods/permissions-grant.json +++ b/json-schemas/interface-methods/permissions-grant.json @@ -9,7 +9,7 @@ "additionalProperties": false, "properties": { "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "delegationChain": { "description": "the parent grant", @@ -71,4 +71,4 @@ } } } -} +} \ No newline at end of file diff --git a/json-schemas/interface-methods/permissions-request.json b/json-schemas/interface-methods/permissions-request.json index f1442fa51..a320870c4 100644 --- a/json-schemas/interface-methods/permissions-request.json +++ b/json-schemas/interface-methods/permissions-request.json @@ -9,7 +9,7 @@ ], "properties": { "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "descriptor": { "type": "object", diff --git a/json-schemas/interface-methods/permissions-revoke.json b/json-schemas/interface-methods/permissions-revoke.json index d86ac2f9a..64543e876 100644 --- a/json-schemas/interface-methods/permissions-revoke.json +++ b/json-schemas/interface-methods/permissions-revoke.json @@ -9,7 +9,7 @@ "additionalProperties": false, "properties": { "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "descriptor": { "type": "object", diff --git a/json-schemas/interface-methods/protocols-configure.json b/json-schemas/interface-methods/protocols-configure.json index 5c99cfc92..b8526211c 100644 --- a/json-schemas/interface-methods/protocols-configure.json +++ b/json-schemas/interface-methods/protocols-configure.json @@ -9,7 +9,7 @@ ], "properties": { "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "descriptor": { "type": "object", diff --git a/json-schemas/interface-methods/protocols-query.json b/json-schemas/interface-methods/protocols-query.json index f37818c0e..6d9027a4d 100644 --- a/json-schemas/interface-methods/protocols-query.json +++ b/json-schemas/interface-methods/protocols-query.json @@ -8,7 +8,7 @@ ], "properties": { "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "descriptor": { "type": "object", diff --git a/json-schemas/interface-methods/records-delete.json b/json-schemas/interface-methods/records-delete.json index 7f3b48dfd..163a981ef 100644 --- a/json-schemas/interface-methods/records-delete.json +++ b/json-schemas/interface-methods/records-delete.json @@ -9,7 +9,7 @@ ], "properties": { "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "descriptor": { "type": "object", diff --git a/json-schemas/interface-methods/records-query.json b/json-schemas/interface-methods/records-query.json index b99cf3b97..175b57994 100644 --- a/json-schemas/interface-methods/records-query.json +++ b/json-schemas/interface-methods/records-query.json @@ -8,7 +8,7 @@ ], "properties": { "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "descriptor": { "type": "object", @@ -44,7 +44,7 @@ "properties": { "limit": { "type": "number", - "minimum": 1 + "minimum": 1 }, "messageCid": { "type": "string" @@ -63,4 +63,4 @@ } } } -} +} \ No newline at end of file diff --git a/json-schemas/interface-methods/records-read.json b/json-schemas/interface-methods/records-read.json index aacf0e87c..0e43dd97a 100644 --- a/json-schemas/interface-methods/records-read.json +++ b/json-schemas/interface-methods/records-read.json @@ -8,7 +8,7 @@ ], "properties": { "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "descriptor": { "type": "object", diff --git a/json-schemas/interface-methods/records-write-unidentified.json b/json-schemas/interface-methods/records-write-unidentified.json index 6c955520b..9ac54d9b6 100644 --- a/json-schemas/interface-methods/records-write-unidentified.json +++ b/json-schemas/interface-methods/records-write-unidentified.json @@ -17,7 +17,7 @@ "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" }, "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "encryption": { "type": "object", @@ -268,4 +268,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/json-schemas/interface-methods/snapshots-create.json b/json-schemas/interface-methods/snapshots-create.json index 7ebaed786..52d6af0c9 100644 --- a/json-schemas/interface-methods/snapshots-create.json +++ b/json-schemas/interface-methods/snapshots-create.json @@ -9,7 +9,7 @@ ], "properties": { "authorization": { - "$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json" + "$ref": "https://identity.foundation/dwn/json-schemas/authorization.json" }, "descriptor": { "type": "object", diff --git a/src/core/auth.ts b/src/core/auth.ts index f4ace38a2..46b59e089 100644 --- a/src/core/auth.ts +++ b/src/core/auth.ts @@ -1,8 +1,7 @@ import type { CID } from 'multiformats'; import type { DidResolver } from '../did/did-resolver.js'; -import type { GeneralJws } from '../types/jws-types.js'; -import type { GenericMessage } from '../types/message-types.js'; import type { Message } from './message.js'; +import type { AuthorizationModel, GenericMessage } from '../types/message-types.js'; import { Cid } from '../utils/cid.js'; import { GeneralJwsVerifier } from '../jose/jws/general/verifier.js'; @@ -38,12 +37,12 @@ export async function validateAuthorizationIntegrity( throw new DwnError(DwnErrorCode.AuthorizationMissing, 'Property `authorization` is missing.'); } - if (message.authorization.signatures.length !== 1) { + if (message.authorization.author.signatures.length !== 1) { throw new Error('expected no more than 1 signature for authorization'); } // validate payload integrity - const payloadJson = Jws.decodePlainObjectPayload(message.authorization); + const payloadJson = Jws.decodePlainObjectPayload(message.authorization.author); validateJsonSchema(jsonSchemaKey, payloadJson); @@ -62,12 +61,12 @@ export async function validateAuthorizationIntegrity( * Validates the signature(s) of the given JWS. * @throws {Error} if fails authentication */ -export async function authenticate(jws: GeneralJws | undefined, didResolver: DidResolver): Promise { - if (jws === undefined) { +export async function authenticate(authorizationModel: AuthorizationModel | undefined, didResolver: DidResolver): Promise { + if (authorizationModel === undefined) { throw new DwnError(DwnErrorCode.AuthenticateJwsMissing, 'Missing JWS.'); } - const verifier = new GeneralJwsVerifier(jws); + const verifier = new GeneralJwsVerifier(authorizationModel.author); await verifier.verify(didResolver); } diff --git a/src/core/message.ts b/src/core/message.ts index 6d69e7a62..bf0ef3d2e 100644 --- a/src/core/message.ts +++ b/src/core/message.ts @@ -7,7 +7,7 @@ import { removeUndefinedProperties } from '../utils/object.js'; import type { Signer } from '../types/signer.js'; import { validateJsonSchema } from '../schema-validator.js'; -import type { BaseAuthorizationPayload, Descriptor, GenericMessage } from '../types/message-types.js'; +import type { AuthorizationModel, BaseAuthorizationPayload, Descriptor, GenericMessage } from '../types/message-types.js'; export enum DwnInterfaceName { Events = 'Events', @@ -42,7 +42,7 @@ export abstract class Message { this.message = message; if (message.authorization !== undefined) { - this.authorizationPayload = Jws.decodePlainObjectPayload(message.authorization); + this.authorizationPayload = Jws.decodePlainObjectPayload(message.authorization.author); this.author = Message.getAuthor(message as GenericMessage); } } @@ -75,7 +75,7 @@ export abstract class Message { return undefined; } - const author = Jws.getSignerDid(message.authorization.signatures[0]); + const author = Jws.getSignerDid(message.authorization.author.signatures[0]); return author; } @@ -133,15 +133,15 @@ export abstract class Message { } /** - * Signs over the CID of provided `descriptor`. The output is used as an `authorization` property. - * @param signatureInput - the signature material to use (e.g. key and header data) + * Creates the `authorization` as the author to be used in a DWN message. + * @param signer Signer as the author * @returns General JWS signature used as an `authorization` property. */ - public static async signAsAuthorization( + public static async signAuthorizationAsAuthor( descriptor: Descriptor, - signatureInput: Signer, + signer: Signer, additionalPayloadProperties?: { permissionsGrantId?: string, protocolRole?: string } - ): Promise { + ): Promise { const descriptorCid = await Cid.computeCid(descriptor); const authPayload: BaseAuthorizationPayload = { descriptorCid, ...additionalPayloadProperties }; @@ -149,9 +149,11 @@ export abstract class Message { const authPayloadStr = JSON.stringify(authPayload); const authPayloadBytes = new TextEncoder().encode(authPayloadStr); - const builder = await GeneralJwsBuilder.create(authPayloadBytes, [signatureInput]); + const builder = await GeneralJwsBuilder.create(authPayloadBytes, [signer]); + const authorJws = builder.getJws(); - return builder.getJws(); + const authorization = { author: authorJws }; + return authorization; } /** diff --git a/src/handlers/records-query.ts b/src/handlers/records-query.ts index 07a4f5e4e..059f18cb2 100644 --- a/src/handlers/records-query.ts +++ b/src/handlers/records-query.ts @@ -2,7 +2,7 @@ import type { MethodHandler } from '../types/method-handler.js'; import type { RecordsWriteMessageWithOptionalEncodedData } from '../store/storage-controller.js'; import type { DataStore, DidResolver, MessageStore } from '../index.js'; import type { Filter, GenericMessage, MessageSort } from '../types/message-types.js'; -import type { RecordsQueryMessage, RecordsQueryReply, RecordsQueryReplyEntry } from '../types/records-types.js'; +import type { RecordsQueryMessage, RecordsQueryReply } from '../types/records-types.js'; import { authenticate } from '../core/auth.js'; import { messageReplyFromError } from '../core/message-reply.js'; @@ -53,28 +53,13 @@ export class RecordsQueryHandler implements MethodHandler { } } - const entries = RecordsQueryHandler.removeAuthorization(recordsWrites); - return { - status: { code: 200, detail: 'OK' }, - entries, + status : { code: 200, detail: 'OK' }, + entries : recordsWrites, paginationMessageCid }; } - /** - * Removes `authorization` property from each and every `RecordsWrite` message given and returns the result as a different array. - */ - private static removeAuthorization(recordsWriteMessages: RecordsWriteMessageWithOptionalEncodedData[]): RecordsQueryReplyEntry[] { - const recordsQueryReplyEntries: RecordsQueryReplyEntry[] = []; - for (const record of recordsWriteMessages) { - const { authorization: _, ...objectWithRemainingProperties } = record; // a trick to stripping away `authorization` - recordsQueryReplyEntries.push(objectWithRemainingProperties); - } - - return recordsQueryReplyEntries; - } - /** * Convert an incoming DateSort to a sort type accepted by MessageStore * Defaults to 'dateCreated' in Descending order if no sort is supplied. diff --git a/src/handlers/records-read.ts b/src/handlers/records-read.ts index 1fbf2fcd6..7ea3778ae 100644 --- a/src/handlers/records-read.ts +++ b/src/handlers/records-read.ts @@ -79,11 +79,10 @@ export class RecordsReadHandler implements MethodHandler { data = result.dataStream; } - const { authorization: _, ...recordsWriteWithoutAuthorization } = newestRecordsWrite; // a trick to stripping away `authorization` - const messageReply: RecordsReadReply ={ + const messageReply: RecordsReadReply = { status : { code: 200, detail: 'OK' }, record : { - ...recordsWriteWithoutAuthorization, + ...newestRecordsWrite, data, } }; diff --git a/src/interfaces/events-get.ts b/src/interfaces/events-get.ts index 47f350e68..af17559ca 100644 --- a/src/interfaces/events-get.ts +++ b/src/interfaces/events-get.ts @@ -31,7 +31,7 @@ export class EventsGet extends Message { descriptor.watermark = options.watermark; } - const authorization = await Message.signAsAuthorization(descriptor, options.authorizationSigner); + const authorization = await Message.signAuthorizationAsAuthor(descriptor, options.authorizationSigner); const message = { descriptor, authorization }; Message.validateJsonSchema(message); diff --git a/src/interfaces/hooks-write.ts b/src/interfaces/hooks-write.ts index 273fadb32..1fab1d591 100644 --- a/src/interfaces/hooks-write.ts +++ b/src/interfaces/hooks-write.ts @@ -43,7 +43,7 @@ export class HooksWrite extends Message { // Error: `undefined` is not supported by the IPLD Data Model and cannot be encoded removeUndefinedProperties(descriptor); - const authorization = await Message.signAsAuthorization(descriptor, options.authorizationSigner); + const authorization = await Message.signAuthorizationAsAuthor(descriptor, options.authorizationSigner); const message = { descriptor, authorization }; Message.validateJsonSchema(message); diff --git a/src/interfaces/messages-get.ts b/src/interfaces/messages-get.ts index b1d49c56a..6e943a502 100644 --- a/src/interfaces/messages-get.ts +++ b/src/interfaces/messages-get.ts @@ -30,7 +30,7 @@ export class MessagesGet extends Message { messageTimestamp : options?.messageTimestamp ?? getCurrentTimeInHighPrecision(), }; - const authorization = await Message.signAsAuthorization(descriptor, options.authorizationSigner); + const authorization = await Message.signAuthorizationAsAuthor(descriptor, options.authorizationSigner); const message = { descriptor, authorization }; Message.validateJsonSchema(message); diff --git a/src/interfaces/permissions-grant.ts b/src/interfaces/permissions-grant.ts index 16a1a59af..bddc45856 100644 --- a/src/interfaces/permissions-grant.ts +++ b/src/interfaces/permissions-grant.ts @@ -60,7 +60,7 @@ export class PermissionsGrant extends Message { // Error: `undefined` is not supported by the IPLD Data Model and cannot be encoded removeUndefinedProperties(descriptor); - const authorization = await Message.signAsAuthorization(descriptor, options.authorizationSigner); + const authorization = await Message.signAuthorizationAsAuthor(descriptor, options.authorizationSigner); const message: PermissionsGrantMessage = { descriptor, authorization }; Message.validateJsonSchema(message); diff --git a/src/interfaces/permissions-request.ts b/src/interfaces/permissions-request.ts index e154a9c02..6e7a6bdab 100644 --- a/src/interfaces/permissions-request.ts +++ b/src/interfaces/permissions-request.ts @@ -43,7 +43,7 @@ export class PermissionsRequest extends Message { // Error: `undefined` is not supported by the IPLD Data Model and cannot be encoded removeUndefinedProperties(descriptor); - const auth = await Message.signAsAuthorization(descriptor, options.authorizationSigner); + const auth = await Message.signAuthorizationAsAuthor(descriptor, options.authorizationSigner); const message: PermissionsRequestMessage = { descriptor, authorization: auth }; Message.validateJsonSchema(message); diff --git a/src/interfaces/permissions-revoke.ts b/src/interfaces/permissions-revoke.ts index 4817150d8..63e9c1ba9 100644 --- a/src/interfaces/permissions-revoke.ts +++ b/src/interfaces/permissions-revoke.ts @@ -27,7 +27,7 @@ export class PermissionsRevoke extends Message { permissionsGrantId : options.permissionsGrantId, }; - const authorization = await Message.signAsAuthorization(descriptor, options.authorizationSigner); + const authorization = await Message.signAuthorizationAsAuthor(descriptor, options.authorizationSigner); const message: PermissionsRevokeMessage = { descriptor, authorization }; Message.validateJsonSchema(message); diff --git a/src/interfaces/protocols-configure.ts b/src/interfaces/protocols-configure.ts index fa6e195bd..96d7657b0 100644 --- a/src/interfaces/protocols-configure.ts +++ b/src/interfaces/protocols-configure.ts @@ -34,7 +34,7 @@ export class ProtocolsConfigure extends Message { definition : ProtocolsConfigure.normalizeDefinition(options.definition) }; - const authorization = await Message.signAsAuthorization( + const authorization = await Message.signAuthorizationAsAuthor( descriptor, options.authorizationSigner, { permissionsGrantId: options.permissionsGrantId } diff --git a/src/interfaces/protocols-query.ts b/src/interfaces/protocols-query.ts index fc7029aec..7e2a99e62 100644 --- a/src/interfaces/protocols-query.ts +++ b/src/interfaces/protocols-query.ts @@ -1,4 +1,4 @@ -import type { GeneralJws } from '../types/jws-types.js'; +import type { AuthorizationModel } from '../types/message-types.js'; import type { MessageStore } from '../types/message-store.js'; import type { Signer } from '../types/signer.js'; import type { ProtocolsQueryDescriptor, ProtocolsQueryFilter, ProtocolsQueryMessage } from '../types/protocols-types.js'; @@ -46,9 +46,9 @@ export class ProtocolsQuery extends Message { removeUndefinedProperties(descriptor); // only generate the `authorization` property if signature input is given - let authorization: GeneralJws | undefined; + let authorization: AuthorizationModel | undefined; if (options.authorizationSigner !== undefined) { - authorization = await Message.signAsAuthorization( + authorization = await Message.signAuthorizationAsAuthor( descriptor, options.authorizationSigner, { permissionsGrantId: options.permissionsGrantId } diff --git a/src/interfaces/records-delete.ts b/src/interfaces/records-delete.ts index 2a0366eec..b245e9ef3 100644 --- a/src/interfaces/records-delete.ts +++ b/src/interfaces/records-delete.ts @@ -38,7 +38,7 @@ export class RecordsDelete extends Message { messageTimestamp : options.messageTimestamp ?? currentTime }; - const authorization = await Message.signAsAuthorization(descriptor, options.authorizationSigner); + const authorization = await Message.signAuthorizationAsAuthor(descriptor, options.authorizationSigner); const message: RecordsDeleteMessage = { descriptor, authorization }; Message.validateJsonSchema(message); diff --git a/src/interfaces/records-query.ts b/src/interfaces/records-query.ts index 1e67ecd6c..19a9d64af 100644 --- a/src/interfaces/records-query.ts +++ b/src/interfaces/records-query.ts @@ -58,7 +58,7 @@ export class RecordsQuery extends Message { // only generate the `authorization` property if signature input is given const authorizationSigner = options.authorizationSigner; - const authorization = authorizationSigner ? await Message.signAsAuthorization(descriptor, authorizationSigner) : undefined; + const authorization = authorizationSigner ? await Message.signAuthorizationAsAuthor(descriptor, authorizationSigner) : undefined; const message = { descriptor, authorization }; Message.validateJsonSchema(message); diff --git a/src/interfaces/records-read.ts b/src/interfaces/records-read.ts index 26bfbcc20..39b24c10d 100644 --- a/src/interfaces/records-read.ts +++ b/src/interfaces/records-read.ts @@ -59,7 +59,7 @@ export class RecordsRead extends Message { // only generate the `authorization` property if signature input is given let authorization = undefined; if (authorizationSigner !== undefined) { - authorization = await Message.signAsAuthorization(descriptor, authorizationSigner, { permissionsGrantId, protocolRole }); + authorization = await Message.signAuthorizationAsAuthor(descriptor, authorizationSigner, { permissionsGrantId, protocolRole }); } const message: RecordsReadMessage = { descriptor, authorization }; diff --git a/src/interfaces/records-write.ts b/src/interfaces/records-write.ts index 18450c0c7..a5e9603a1 100644 --- a/src/interfaces/records-write.ts +++ b/src/interfaces/records-write.ts @@ -1,14 +1,14 @@ import type { GeneralJws } from '../types/jws-types.js'; -import type { GenericMessage } from '../types/message-types.js'; import type { MessageStore } from '../types/message-store.js'; import type { PublicJwk } from '../types/jose-types.js'; import type { Signer } from '../types/signer.js'; +import type { AuthorizationModel, GenericMessage } from '../types/message-types.js'; import type { EncryptedKey, EncryptionProperty, InternalRecordsWriteMessage, RecordsWriteAttestationPayload, - RecordsWriteAuthorizationPayload, + RecordsWriteAuthorSignaturePayload, RecordsWriteDescriptor, RecordsWriteMessage, UnsignedRecordsWriteMessage @@ -142,12 +142,12 @@ export class RecordsWrite { return this._author; } - private _authorizationPayload: RecordsWriteAuthorizationPayload | undefined; + private _authorSignaturePayload: RecordsWriteAuthorSignaturePayload | undefined; /** * Decoded authorization payload. */ - public get authorizationPayload(): RecordsWriteAuthorizationPayload | undefined { - return this._authorizationPayload; + public get authorizationPayload(): RecordsWriteAuthorSignaturePayload | undefined { + return this._authorSignaturePayload; } readonly attesters: string[]; @@ -156,7 +156,7 @@ export class RecordsWrite { this._message = message; if (message.authorization !== undefined) { - this._authorizationPayload = Jws.decodePlainObjectPayload(message.authorization); + this._authorSignaturePayload = Jws.decodePlainObjectPayload(message.authorization.author); this._author = Message.getAuthor(message as GenericMessage); } @@ -167,7 +167,7 @@ export class RecordsWrite { public static async parse(message: RecordsWriteMessage): Promise { // asynchronous checks that are required by the constructor to initialize members properly - await validateAuthorizationIntegrity(message, 'RecordsWriteAuthorizationPayload'); + await validateAuthorizationIntegrity(message, 'RecordsWriteAuthorSignaturePayload'); await RecordsWrite.validateAttestationIntegrity(message); const recordsWrite = new RecordsWrite(message); @@ -354,7 +354,7 @@ export class RecordsWrite { // opportunity here to re-sign instead of remove delete this._message.authorization; - this._authorizationPayload = undefined; + this._authorSignaturePayload = undefined; this._author = undefined; } @@ -389,7 +389,7 @@ export class RecordsWrite { this._message.authorization = authorization; // there is opportunity to optimize here as the payload is constructed within `createAuthorization(...)` - this._authorizationPayload = Jws.decodePlainObjectPayload(authorization); + this._authorSignaturePayload = Jws.decodePlainObjectPayload(authorization.author); this._author = author; } @@ -651,8 +651,8 @@ export class RecordsWrite { encryption: EncryptionProperty | undefined, signer: Signer, permissionsGrantId: string | undefined, - ): Promise { - const authorizationPayload: RecordsWriteAuthorizationPayload = { + ): Promise { + const authorizationPayload: RecordsWriteAuthorSignaturePayload = { recordId, descriptorCid }; @@ -665,11 +665,16 @@ export class RecordsWrite { if (encryptionCid !== undefined) { authorizationPayload.encryptionCid = encryptionCid; } // assign `encryptionCid` only if it is defined if (permissionsGrantId !== undefined) { authorizationPayload.permissionsGrantId = permissionsGrantId; } - const authorizationPayloadBytes = Encoder.objectToBytes(authorizationPayload); const builder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signer]); - return builder.getJws(); + const authorJws = builder.getJws(); + + const authorization = { + author: authorJws + }; + + return authorization; } /** diff --git a/src/interfaces/snapshots-create.ts b/src/interfaces/snapshots-create.ts index eb738b1fd..953f909f5 100644 --- a/src/interfaces/snapshots-create.ts +++ b/src/interfaces/snapshots-create.ts @@ -32,7 +32,7 @@ export class SnapshotsCreate extends Message { definitionCid }; - const authorization = await Message.signAsAuthorization(descriptor, options.authorizationSigner); + const authorization = await Message.signAuthorizationAsAuthor(descriptor, options.authorizationSigner); const message = { descriptor, authorization }; Message.validateJsonSchema(message); diff --git a/src/types/message-types.ts b/src/types/message-types.ts index 5341e35af..aac67eb96 100644 --- a/src/types/message-types.ts +++ b/src/types/message-types.ts @@ -4,8 +4,15 @@ import type { GeneralJws } from './jws-types.js'; * Intersection type for all concrete message types. */ export type GenericMessage = { - descriptor: Descriptor - authorization?: GeneralJws; + descriptor: Descriptor; + authorization?: AuthorizationModel; +}; + +/** + * The data model for the `authorization` property in a DWN message. + */ +export type AuthorizationModel = { + author: GeneralJws; }; /** diff --git a/src/types/records-types.ts b/src/types/records-types.ts index e64b14c04..8f5beff8c 100644 --- a/src/types/records-types.ts +++ b/src/types/records-types.ts @@ -5,7 +5,7 @@ import type { GenericMessageReply } from '../core/message-reply.js'; import type { KeyDerivationScheme } from '../utils/hd-key.js'; import type { PublicJwk } from './jose-types.js'; import type { Readable } from 'readable-stream'; -import type { BaseAuthorizationPayload, GenericMessage, Pagination } from './message-types.js'; +import type { AuthorizationModel, BaseAuthorizationPayload, GenericMessage, Pagination } from './message-types.js'; import type { DwnInterfaceName, DwnMethodName } from '../core/message.js'; export type RecordsWriteDescriptor = { @@ -123,7 +123,7 @@ export type RecordsWriteAttestationPayload = { descriptorCid: string; }; -export type RecordsWriteAuthorizationPayload = BaseAuthorizationPayload & { +export type RecordsWriteAuthorSignaturePayload = BaseAuthorizationPayload & { recordId: string; contextId?: string; attestationCid?: string; @@ -140,18 +140,12 @@ export type RecordsQueryReply = GenericMessageReply & { }; export type RecordsReadMessage = { - authorization?: GeneralJws; + authorization?: AuthorizationModel; descriptor: RecordsReadDescriptor; }; export type RecordsReadReply = GenericMessageReply & { - record?: { - recordId: string, - contextId?: string; - descriptor: RecordsWriteDescriptor; - // authorization: GeneralJws; // intentionally omitted - attestation?: GeneralJws; - encryption?: EncryptionProperty; + record?: RecordsWriteMessage & { data: Readable; } }; diff --git a/src/utils/jws.ts b/src/utils/jws.ts index ae56a0eab..61416a38d 100644 --- a/src/utils/jws.ts +++ b/src/utils/jws.ts @@ -78,8 +78,8 @@ export class Jws { * Creates a Signer[] from the given Personas. */ public static createSigners(keyMaterials: KeyMaterial[]): Signer[] { - const signatureInputs = keyMaterials.map((keyMaterial) => Jws.createSigner(keyMaterial)); - return signatureInputs; + const signers = keyMaterials.map((keyMaterial) => Jws.createSigner(keyMaterial)); + return signers; } /** diff --git a/tests/handlers/permissions-grant.spec.ts b/tests/handlers/permissions-grant.spec.ts index fb8b989f9..db7c42dbf 100644 --- a/tests/handlers/permissions-grant.spec.ts +++ b/tests/handlers/permissions-grant.spec.ts @@ -169,7 +169,7 @@ export function testPermissionsGrantHandler(): void { schema : 'some-schema', protocol : 'some-protocol' }; - schemaAndProtocolGrant.message.authorization = await Message.signAsAuthorization( + schemaAndProtocolGrant.message.authorization = await Message.signAuthorizationAsAuthor( schemaAndProtocolGrant.message.descriptor, Jws.createSigner(alice) ); @@ -187,7 +187,7 @@ export function testPermissionsGrantHandler(): void { schema : 'some-schema', contextId : 'some-context-id' }; - schemaAndContextIdGrant.message.authorization = await Message.signAsAuthorization( + schemaAndContextIdGrant.message.authorization = await Message.signAuthorizationAsAuthor( schemaAndContextIdGrant.message.descriptor, Jws.createSigner(alice) ); @@ -205,7 +205,7 @@ export function testPermissionsGrantHandler(): void { schema : 'some-schema', protocolPath : 'some-protocol-path' }; - schemaAndProtocolPathGrant.message.authorization = await Message.signAsAuthorization( + schemaAndProtocolPathGrant.message.authorization = await Message.signAuthorizationAsAuthor( schemaAndProtocolPathGrant.message.descriptor, Jws.createSigner(alice) ); @@ -237,7 +237,7 @@ export function testPermissionsGrantHandler(): void { contextId : 'some-context-id', protocolPath : 'some-protocol-path', }; - contextIdAndProtocolPathGrant.message.authorization = await Message.signAsAuthorization( + contextIdAndProtocolPathGrant.message.authorization = await Message.signAuthorizationAsAuthor( contextIdAndProtocolPathGrant.message.descriptor, Jws.createSigner(alice) ); diff --git a/tests/handlers/protocols-configure.spec.ts b/tests/handlers/protocols-configure.spec.ts index 2fe0da175..a57d73499 100644 --- a/tests/handlers/protocols-configure.spec.ts +++ b/tests/handlers/protocols-configure.spec.ts @@ -80,13 +80,13 @@ export function testProtocolsConfigureHandler(): void { // intentionally create more than one signature, which is not allowed const extraRandomPersona = await TestDataGenerator.generatePersona(); - const signatureInput1 = Jws.createSigner(author); - const signatureInput2 = Jws.createSigner(extraRandomPersona); + const signer1 = Jws.createSigner(author); + const signer2 = Jws.createSigner(extraRandomPersona); const authorizationPayloadBytes = Encoder.objectToBytes(protocolsConfigure.authorizationPayload!); - const jwsBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signatureInput1, signatureInput2]); - message.authorization = jwsBuilder.getJws(); + const jwsBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signer1, signer2]); + message.authorization = { author: jwsBuilder.getJws() }; TestStubGenerator.stubDidResolver(didResolver, [author]); @@ -231,7 +231,7 @@ export function testProtocolsConfigureHandler(): void { protocolsConfig.message.descriptor.definition.protocol = 'example.com/'; // Re-create auth because we altered the descriptor after signing - protocolsConfig.message.authorization = await Message.signAsAuthorization( + protocolsConfig.message.authorization = await Message.signAuthorizationAsAuthor( protocolsConfig.message.descriptor, Jws.createSigner(alice) ); @@ -255,7 +255,7 @@ export function testProtocolsConfigureHandler(): void { protocolsConfig.message.descriptor.definition.types.ask.schema = 'ask'; // Re-create auth because we altered the descriptor after signing - protocolsConfig.message.authorization = await Message.signAsAuthorization( + protocolsConfig.message.authorization = await Message.signAuthorizationAsAuthor( protocolsConfig.message.descriptor, Jws.createSigner(alice) ); diff --git a/tests/handlers/protocols-query.spec.ts b/tests/handlers/protocols-query.spec.ts index 2840a2477..eec42da65 100644 --- a/tests/handlers/protocols-query.spec.ts +++ b/tests/handlers/protocols-query.spec.ts @@ -149,7 +149,7 @@ export function testProtocolsQueryHandler(): void { protocolsQuery.message.descriptor.filter!.protocol = 'example.com/'; // Re-create auth because we altered the descriptor after signing - protocolsQuery.message.authorization = await Message.signAsAuthorization( + protocolsQuery.message.authorization = await Message.signAuthorizationAsAuthor( protocolsQuery.message.descriptor, Jws.createSigner(alice) ); @@ -169,9 +169,9 @@ export function testProtocolsQueryHandler(): void { const authorizationPayload = { ...protocolsQuery.authorizationPayload }; authorizationPayload.descriptorCid = incorrectDescriptorCid; const authorizationPayloadBytes = Encoder.objectToBytes(authorizationPayload); - const signatureInput = Jws.createSigner(author); - const jwsBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signatureInput]); - message.authorization = jwsBuilder.getJws(); + const signer = Jws.createSigner(author); + const jwsBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signer]); + message.authorization = { author: jwsBuilder.getJws() }; const reply = await dwn.processMessage(tenant, message); diff --git a/tests/handlers/records-query.spec.ts b/tests/handlers/records-query.spec.ts index eca250ab5..284a9d34d 100644 --- a/tests/handlers/records-query.spec.ts +++ b/tests/handlers/records-query.spec.ts @@ -66,12 +66,13 @@ export function testRecordsQueryHandler(): void { await dwn.close(); }); - it('should return recordId, descriptor, and attestation', async () => { + it('should return recordId, descriptor, authorization and attestation', async () => { const alice = await TestDataGenerator.generatePersona(); - TestStubGenerator.stubDidResolver(didResolver, [alice]); + const bob = await TestDataGenerator.generatePersona(); + TestStubGenerator.stubDidResolver(didResolver, [alice, bob]); const dataFormat = 'myAwesomeDataFormat'; - const write = await TestDataGenerator.generateRecordsWrite({ author: alice, dataFormat }); + const write = await TestDataGenerator.generateRecordsWrite({ author: alice, attesters: [bob], dataFormat }); const writeReply = await dwn.processMessage(alice.did, write.message, write.dataStream); expect(writeReply.status.code).to.equal(202); @@ -80,7 +81,8 @@ export function testRecordsQueryHandler(): void { expect(reply.entries?.length).to.equal(1); const entry = reply.entries![0]; - expect(entry.attestation).to.equal(write.message.attestation); + expect(entry.authorization).to.deep.equal(write.message.authorization); + expect(entry.attestation).to.deep.equal(write.message.attestation); expect(entry.descriptor).to.deep.equal(write.message.descriptor); expect(entry.recordId).to.equal(write.message.recordId); }); @@ -302,7 +304,7 @@ export function testRecordsQueryHandler(): void { expect(reply.entries![0].encodedData).to.equal(Encoder.bytesToBase64Url(write2.dataBytes!)); }); - it('should not include `authorization` in returned records', async () => { + it('should include `authorization` in returned records', async () => { const alice = await TestDataGenerator.generatePersona(); const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice }); @@ -321,7 +323,7 @@ export function testRecordsQueryHandler(): void { const queryReply = await dwn.processMessage(alice.did, queryData.message); expect(queryReply.status.code).to.equal(200); expect(queryReply.entries?.length).to.equal(1); - expect((queryReply.entries![0] as any).authorization).to.equal(undefined); + expect((queryReply.entries![0] as any).authorization).to.deep.equal(message.authorization); }); it('should include `attestation` in returned records', async () => { @@ -916,7 +918,7 @@ export function testRecordsQueryHandler(): void { recordsQuery.message.descriptor.filter.protocol = 'example.com/'; // Re-create auth because we altered the descriptor after signing - recordsQuery.message.authorization = await Message.signAsAuthorization( + recordsQuery.message.authorization = await Message.signAuthorizationAsAuthor( recordsQuery.message.descriptor, Jws.createSigner(alice) ); @@ -940,7 +942,7 @@ export function testRecordsQueryHandler(): void { recordsQuery.message.descriptor.filter.schema = 'example.com/'; // Re-create auth because we altered the descriptor after signing - recordsQuery.message.authorization = await Message.signAsAuthorization( + recordsQuery.message.authorization = await Message.signAuthorizationAsAuthor( recordsQuery.message.descriptor, Jws.createSigner(alice) ); diff --git a/tests/handlers/records-read.spec.ts b/tests/handlers/records-read.spec.ts index 60dc3d90b..d340af222 100644 --- a/tests/handlers/records-read.spec.ts +++ b/tests/handlers/records-read.spec.ts @@ -88,7 +88,8 @@ export function testRecordsReadHandler(): void { const readReply = await dwn.handleRecordsRead(alice.did, recordsRead.message); expect(readReply.status.code).to.equal(200); expect(readReply.record).to.exist; - expect(readReply.record?.descriptor).to.exist; + expect(readReply.record?.authorization).to.deep.equal(message.authorization); + expect(readReply.record?.descriptor).to.deep.equal(message.descriptor); const dataFetched = await DataStream.toBytes(readReply.record!.data!); expect(ArrayUtility.byteArraysEqual(dataFetched, dataBytes!)).to.be.true; diff --git a/tests/handlers/records-write.spec.ts b/tests/handlers/records-write.spec.ts index 51bf80bda..0ee9af77e 100644 --- a/tests/handlers/records-write.spec.ts +++ b/tests/handlers/records-write.spec.ts @@ -2772,9 +2772,9 @@ export function testRecordsWriteHandler(): void { const authorizationPayload = { ...recordsWrite.authorizationPayload }; authorizationPayload.recordId = await TestDataGenerator.randomCborSha256Cid(); // make recordId mismatch in authorization payload const authorizationPayloadBytes = Encoder.objectToBytes(authorizationPayload); - const signatureInput = Jws.createSigner(author); - const jwsBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signatureInput]); - message.authorization = jwsBuilder.getJws(); + const signer = Jws.createSigner(author); + const jwsBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signer]); + message.authorization = { author: jwsBuilder.getJws() }; const tenant = author.did; const didResolver = TestStubGenerator.createDidResolverStub(author); @@ -2796,9 +2796,9 @@ export function testRecordsWriteHandler(): void { const authorizationPayload = { ...recordsWrite.authorizationPayload }; authorizationPayload.contextId = await TestDataGenerator.randomCborSha256Cid(); // make contextId mismatch in authorization payload const authorizationPayloadBytes = Encoder.objectToBytes(authorizationPayload); - const signatureInput = Jws.createSigner(author); - const jwsBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signatureInput]); - message.authorization = jwsBuilder.getJws(); + const signer = Jws.createSigner(author); + const jwsBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signer]); + message.authorization = { author: jwsBuilder.getJws() }; const tenant = author.did; const didResolver = sinon.createStubInstance(DidResolver); @@ -2851,21 +2851,21 @@ export function testRecordsWriteHandler(): void { it('should fail with 400 if `attestation` payload contains properties other than `descriptorCid`', async () => { const { author, message, recordsWrite, dataStream } = await TestDataGenerator.generateRecordsWrite(); const tenant = author.did; - const signatureInput = Jws.createSigner(author); + const signer = Jws.createSigner(author); // replace `attestation` with one that has an additional property, but go the extra mile of making sure signature is valid const descriptorCid = recordsWrite.authorizationPayload!.descriptorCid; const attestationPayload = { descriptorCid, someAdditionalProperty: 'anyValue' }; // additional property is not allowed const attestationPayloadBytes = Encoder.objectToBytes(attestationPayload); - const attestationBuilder = await GeneralJwsBuilder.create(attestationPayloadBytes, [signatureInput]); + const attestationBuilder = await GeneralJwsBuilder.create(attestationPayloadBytes, [signer]); message.attestation = attestationBuilder.getJws(); // recreate the `authorization` based on the new` attestationCid` const authorizationPayload = { ...recordsWrite.authorizationPayload }; authorizationPayload.attestationCid = await Cid.computeCid(attestationPayload); const authorizationPayloadBytes = Encoder.objectToBytes(authorizationPayload); - const authorizationBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signatureInput]); - message.authorization = authorizationBuilder.getJws(); + const authorizationBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signer]); + message.authorization = { author: authorizationBuilder.getJws() }; const didResolver = TestStubGenerator.createDidResolverStub(author); const messageStore = stubInterface(); diff --git a/tests/interfaces/records-write.spec.ts b/tests/interfaces/records-write.spec.ts index c60f7c1e2..a796a11e0 100644 --- a/tests/interfaces/records-write.spec.ts +++ b/tests/interfaces/records-write.spec.ts @@ -222,7 +222,7 @@ describe('RecordsWrite', () => { const recordsWrite = await RecordsWrite.create(options); - expect(recordsWrite.message.authorization!.signatures[0].signature).to.equal(Encoder.bytesToBase64Url(hardCodedSignature)); + expect(recordsWrite.message.authorization!.author.signatures[0].signature).to.equal(Encoder.bytesToBase64Url(hardCodedSignature)); }); it('should throw if attempting to use `protocols` key derivation encryption scheme on non-protocol-based record', async () => { diff --git a/tests/utils/test-data-generator.ts b/tests/utils/test-data-generator.ts index fb01e5261..2b3a82e52 100644 --- a/tests/utils/test-data-generator.ts +++ b/tests/utils/test-data-generator.ts @@ -1,7 +1,7 @@ import type { DidResolutionResult } from '../../src/did/did-resolver.js'; -import type { Pagination } from '../../src/types/message-types.js'; import type { Readable } from 'readable-stream'; import type { RecordsFilter } from '../../src/types/records-types.js'; +import type { AuthorizationModel, Pagination } from '../../src/types/message-types.js'; import type { CreateFromOptions, @@ -769,6 +769,21 @@ export class TestDataGenerator { }; } + /** + * Generates a dummy `authorization` property for a DWN message that only conforms to schema validation. + */ + public static generateAuthorization(): AuthorizationModel { + return { + author: { + payload : 'anyPayload', + signatures : [{ + protected : 'anyProtectedHeader', + signature : 'anySignature' + }] + } + }; + } + /** * Generates a random alpha-numeric string. */ diff --git a/tests/validation/json-schemas/protocols/protocols-configure.spec.ts b/tests/validation/json-schemas/protocols/protocols-configure.spec.ts index 8aa662711..f822dd2c5 100644 --- a/tests/validation/json-schemas/protocols/protocols-configure.spec.ts +++ b/tests/validation/json-schemas/protocols/protocols-configure.spec.ts @@ -1,8 +1,9 @@ -import { expect } from 'chai'; +import type { ProtocolDefinition, ProtocolsConfigureMessage } from '../../../../src/types/protocols-types.js'; +import { expect } from 'chai'; +import { TestDataGenerator } from '../../../utils/test-data-generator.js'; import { validateJsonSchema } from '../../../../src/schema-validator.js'; import { DwnInterfaceName, DwnMethodName, Message } from '../../../../src/core/message.js'; -import type { ProtocolDefinition, ProtocolsConfigureMessage } from '../../../../src/types/protocols-types.js'; describe('ProtocolsConfigure schema definition', () => { it('should throw if unknown actor is encountered in action rule', async () => { @@ -34,13 +35,7 @@ describe('ProtocolsConfigure schema definition', () => { messageTimestamp : '2022-10-14T10:20:30.405060Z', definition : protocolDefinition }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { diff --git a/tests/validation/json-schemas/records/records-query.spec.ts b/tests/validation/json-schemas/records/records-query.spec.ts index f2e4071a0..f07209dd1 100644 --- a/tests/validation/json-schemas/records/records-query.spec.ts +++ b/tests/validation/json-schemas/records/records-query.spec.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import { Message } from '../../../../src/core/message.js'; +import { TestDataGenerator } from '../../../utils/test-data-generator.js'; describe('RecordsQuery schema validation', () => { it('should allow descriptor with only required properties', async () => { @@ -10,13 +11,7 @@ describe('RecordsQuery schema validation', () => { messageTimestamp : '2022-10-14T10:20:30.405060Z', filter : { schema: 'anySchema' } }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, + authorization: TestDataGenerator.generateAuthorization() }; Message.validateJsonSchema(validMessage); }); @@ -29,14 +24,8 @@ describe('RecordsQuery schema validation', () => { messageTimestamp : '2022-10-14T10:20:30.405060Z', filter : { schema: 'anySchema' } }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, - unknownProperty: 'unknownProperty' // unknown property + authorization : TestDataGenerator.generateAuthorization(), + unknownProperty : 'unknownProperty' // unknown property }; expect(() => { @@ -53,13 +42,7 @@ describe('RecordsQuery schema validation', () => { filter : { schema: 'anySchema' }, unknownProperty : 'unknownProperty' // unknown property }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -79,13 +62,7 @@ describe('RecordsQuery schema validation', () => { filter : { schema: 'anySchema' }, dateSort : dateSortValue }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, + authorization: TestDataGenerator.generateAuthorization() }; Message.validateJsonSchema(validMessage); @@ -100,13 +77,7 @@ describe('RecordsQuery schema validation', () => { filter : { schema: 'anySchema' }, dateSort : 'unacceptable', // bad value }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -123,13 +94,7 @@ describe('RecordsQuery schema validation', () => { messageTimestamp : '2022-10-14T10:20:30.405060Z', filter : { } }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -145,13 +110,7 @@ describe('RecordsQuery schema validation', () => { messageTimestamp : '2022-10-14T10:20:30.405060Z', filter : { dateCreated: { } } // empty `dateCreated` criteria }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -167,13 +126,7 @@ describe('RecordsQuery schema validation', () => { messageTimestamp : '2022-10-14T10:20:30.405060Z', filter : { dateCreated: { unexpectedProperty: 'anyValue' } } // unexpected property in `dateCreated` criteria }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { diff --git a/tests/validation/json-schemas/records/records-write.spec.ts b/tests/validation/json-schemas/records/records-write.spec.ts index 506abc0f3..8894d1007 100644 --- a/tests/validation/json-schemas/records/records-write.spec.ts +++ b/tests/validation/json-schemas/records/records-write.spec.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import { Message } from '../../../../src/core/message.js'; +import { TestDataGenerator } from '../../../utils/test-data-generator.js'; describe('RecordsWrite schema definition', () => { it('should allow descriptor with only required properties', async () => { @@ -14,13 +15,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z', }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, + authorization: TestDataGenerator.generateAuthorization() }; Message.validateJsonSchema(validMessage); }); @@ -36,13 +31,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -81,14 +70,8 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, - unknownProperty: 'unknownProperty' // unknown property + authorization : TestDataGenerator.generateAuthorization(), + unknownProperty : 'unknownProperty' // unknown property }; expect(() => { @@ -109,13 +92,7 @@ describe('RecordsWrite schema definition', () => { messageTimestamp : '2022-12-19T10:20:30.123456Z', unknownProperty : 'unknownProperty' // unknown property }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - }, + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -139,13 +116,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; Message.validateJsonSchema(validMessage); @@ -167,13 +138,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -193,13 +158,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; Message.validateJsonSchema(invalidMessage); @@ -218,13 +177,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -245,13 +198,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -275,13 +222,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -304,13 +245,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -333,13 +268,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -363,13 +292,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -394,13 +317,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -425,13 +342,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; Message.validateJsonSchema(invalidMessage); @@ -454,13 +365,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', messageTimestamp : '2022-12-19T10:20:30.123456Z' }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; Message.validateJsonSchema(invalidMessage); @@ -480,13 +385,7 @@ describe('RecordsWrite schema definition', () => { dateCreated : '2022-12-19T10:20:30.123456Z', datePublished : '2022-12-19T10:20:30.123456Z' // must not be present when not published }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -507,13 +406,7 @@ describe('RecordsWrite schema definition', () => { messageTimestamp : '2022-12-19T10:20:30.123456Z', published : true //datePublished must be present }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; expect(() => { @@ -534,13 +427,7 @@ describe('RecordsWrite schema definition', () => { messageTimestamp : '2022-12-19T10:20:30.123456Z', datePublished : '2022-12-19T10:20:30.123456Z' //published must be present }, - authorization: { - payload : 'anyPayload', - signatures : [{ - protected : 'anyProtectedHeader', - signature : 'anySignature' - }] - } + authorization: TestDataGenerator.generateAuthorization() }; expect(() => {