Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add thirdPartyAddress to the Attribute's shareInfo #282

Merged
merged 47 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
3104a0a
feat: add third party address to share info of an attribute
sebbi08 Sep 23, 2024
9bc036a
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Sep 23, 2024
145ba1f
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Sep 23, 2024
88ef386
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Sep 23, 2024
c0c0aad
fix: tests
sebbi08 Sep 24, 2024
c6ecf51
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Sep 25, 2024
f499978
Update packages/consumption/src/modules/attributes/local/CreateShared…
sebbi08 Sep 30, 2024
9bd016e
Update packages/consumption/src/modules/attributes/local/CreateShared…
sebbi08 Sep 30, 2024
057429a
Update packages/consumption/src/modules/attributes/local/LocalAttribu…
sebbi08 Sep 30, 2024
5cd0216
chore: improve third party check
sebbi08 Sep 30, 2024
590ad48
chore: improve third party check
sebbi08 Sep 30, 2024
886837b
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Sep 30, 2024
448e622
chore: revert local settings
sebbi08 Oct 1, 2024
56fdad7
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 1, 2024
6d6726e
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 1, 2024
ce470da
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 2, 2024
e092cc8
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 2, 2024
538f521
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 2, 2024
e9d1ab9
chore: improve error code
sebbi08 Oct 7, 2024
b02c13c
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 7, 2024
a1a6888
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 9, 2024
73217a5
chore: remove eslint ignores
sebbi08 Oct 9, 2024
6b7426d
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 10, 2024
6269a40
chore: rename test functions
sebbi08 Oct 10, 2024
bb88591
chore: rename test functions
sebbi08 Oct 10, 2024
1bc212a
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 11, 2024
75b03e8
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 11, 2024
0609061
feat: add third party address to DVO
sebbi08 Oct 14, 2024
9ddda95
chore: RelationshipAttribute in error text
sebbi08 Oct 14, 2024
d3757cc
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 14, 2024
017050f
chore: pr comments
sebbi08 Oct 15, 2024
edb583c
chore: test lower case
sebbi08 Oct 15, 2024
4881998
chore: change test name
sebbi08 Oct 15, 2024
c5dbb08
chore: remove debugger
sebbi08 Oct 15, 2024
cc9bada
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 16, 2024
cfd3f68
feat: automaticly set the thirdParty address when creating a local at…
sebbi08 Oct 16, 2024
b101240
feat: also forward thirdparty adress in the attribute succession
sebbi08 Oct 16, 2024
3566734
chore: improve js doc wording
sebbi08 Oct 16, 2024
08c4f81
chore: update DVOs
sebbi08 Oct 16, 2024
125a22b
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 17, 2024
89293d4
Merge branch 'main' into feature/add_third_party_adress_to_share_info
mergify[bot] Oct 17, 2024
448df83
chore: PR comments
sebbi08 Oct 17, 2024
5cb9778
chore: pr comments
sebbi08 Oct 21, 2024
983525c
Merge branch 'main' into feature/add_third_party_adress_to_share_info
sebbi08 Oct 21, 2024
43a781b
chore: pr comments
sebbi08 Oct 21, 2024
331bf5f
chore: fix tests
sebbi08 Oct 21, 2024
71836d7
chore: reword error
sebbi08 Oct 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,8 @@ export class AttributesController extends ConsumptionBaseController {
const shareInfo = LocalAttributeShareInfo.from({
peer: parsedParams.peer,
requestReference: parsedParams.requestReference,
sourceAttribute: parsedParams.sourceAttributeId
sourceAttribute: parsedParams.sourceAttributeId,
thirdPartyAddress: parsedParams.thirdPartyAddress
});

const sharedLocalAttributeCopy = await LocalAttribute.fromAttribute(sourceAttribute.content, undefined, shareInfo, parsedParams.attributeId);
Expand All @@ -353,7 +354,8 @@ export class AttributesController extends ConsumptionBaseController {
public async createSharedLocalAttribute(params: ICreateSharedLocalAttributeParams): Promise<LocalAttribute> {
const shareInfo = LocalAttributeShareInfo.from({
peer: params.peer,
requestReference: params.requestReference
requestReference: params.requestReference,
thirdPartyAddress: params.thirdPartyAddress
});
const peerLocalAttribute = LocalAttribute.from({
id: params.id ?? (await ConsumptionIds.attribute.generate()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ export interface CreateSharedLocalAttributeCopyParamsJSON {
sourceAttributeId: string;
peer: string;
requestReference: string;
thirdPartyAddress?: string;
}

export interface ICreateSharedLocalAttributeCopyParams extends ISerializable {
attributeId?: ICoreId;
sourceAttributeId: ICoreId;
peer: ICoreAddress;
requestReference: ICoreId;
thirdPartyAddress?: ICoreAddress;
}

export class CreateSharedLocalAttributeCopyParams extends Serializable implements ICreateSharedLocalAttributeCopyParams {
Expand All @@ -32,6 +34,10 @@ export class CreateSharedLocalAttributeCopyParams extends Serializable implement
@validate()
public requestReference: CoreId;

@serialize()
@validate({ nullable: true })
public thirdPartyAddress: CoreAddress;

public static from(value: ICreateSharedLocalAttributeCopyParams | CreateSharedLocalAttributeCopyParamsJSON): CreateSharedLocalAttributeCopyParams {
return this.fromAny(value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ export interface CreateSharedLocalAttributeParamsJSON {
content: IdentityAttributeJSON | RelationshipAttributeJSON;
requestReferece: string;
peer: string;
thirdPartyAddress?: string;
}

export interface ICreateSharedLocalAttributeParams extends ISerializable {
id?: ICoreId; // needs to be optional because sometimes (e.g. when accepting a CreateAttributeRequestItem) the id is not known yet
content: IIdentityAttribute | IRelationshipAttribute;
requestReference: ICoreId;
peer: ICoreAddress;
thirdPartyAddress?: ICoreAddress;
}

export class CreateSharedLocalAttributeParams extends Serializable implements ICreateSharedLocalAttributeParams {
Expand All @@ -33,6 +35,10 @@ export class CreateSharedLocalAttributeParams extends Serializable implements IC
@validate()
public peer: CoreAddress;

@serialize()
@validate({ nullable: true })
public thirdPartyAddress: CoreAddress;

public static from(value: ICreateSharedLocalAttributeParams | CreateSharedLocalAttributeParamsJSON): CreateSharedLocalAttributeParams {
return this.fromAny(value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@ import { CoreAddress, CoreId, ICoreAddress, ICoreId } from "@nmshd/core-types";
import { nameof } from "ts-simple-nameof";
import { ConsumptionError } from "../../../consumption/ConsumptionError";

/* Either of requestReference or noticicationReference must be set, but not both. */
/* Either of requestReference or notificationReference must be set, but not both. */
export interface LocalAttributeShareInfoJSON {
requestReference?: string;
notificationReference?: string;

peer: string;
sourceAttribute?: string;
thirdPartyAddress?: string;
}

/* Either of requestReference or noticicationReference must be set, but not both. */
/* Either of requestReference or notificationReference must be set, but not both. */
export interface ILocalAttributeShareInfo extends ISerializable {
requestReference?: ICoreId;
notificationReference?: ICoreId;

peer: ICoreAddress;
sourceAttribute?: ICoreId;
thirdPartyAddress?: ICoreAddress;
}

export class LocalAttributeShareInfo extends Serializable implements ILocalAttributeShareInfo {
Expand All @@ -38,6 +38,10 @@ export class LocalAttributeShareInfo extends Serializable implements ILocalAttri
@validate({ nullable: true })
public sourceAttribute?: CoreId;

@serialize()
@validate({ nullable: true })
public thirdPartyAddress: CoreAddress;

public static from(value: ILocalAttributeShareInfo | LocalAttributeShareInfoJSON): LocalAttributeShareInfo {
return super.fromAny(value) as LocalAttributeShareInfo;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,14 @@ export class ReadAttributeRequestItemProcessor extends GenericRequestItemProcess
sharedLocalAttribute = await this.consumptionController.attributes.createSharedLocalAttributeCopy({
sourceAttributeId: CoreId.from(existingSourceAttribute.id),
peer: CoreAddress.from(requestInfo.peer),
requestReference: CoreId.from(requestInfo.id)
requestReference: CoreId.from(requestInfo.id),
thirdPartyAddress: existingSourceAttribute.shareInfo?.peer ? CoreAddress.from(existingSourceAttribute.shareInfo.peer) : undefined
});
return ReadAttributeAcceptResponseItem.from({
result: ResponseItemResult.Accepted,
attributeId: sharedLocalAttribute.id,
attribute: sharedLocalAttribute.content
attribute: sharedLocalAttribute.content,
thirdPartyAddress: sharedLocalAttribute.shareInfo?.thirdPartyAddress
});
}

Expand Down Expand Up @@ -361,7 +363,8 @@ export class ReadAttributeRequestItemProcessor extends GenericRequestItemProcess
id: responseItem.attributeId,
content: responseItem.attribute,
peer: requestInfo.peer,
requestReference: requestInfo.id
requestReference: requestInfo.id,
thirdPartyAddress: responseItem.thirdPartyAddress
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
ShareAttributeAcceptResponseItem,
ShareAttributeRequestItem
} from "@nmshd/content";
import { CoreAddress } from "@nmshd/core-types";
import { CoreAddress, CoreError } from "@nmshd/core-types";
import { RelationshipStatus } from "@nmshd/transport";
import _ from "lodash";
import { ConsumptionCoreErrors } from "../../../../consumption/ConsumptionCoreErrors";
Expand Down Expand Up @@ -130,6 +130,18 @@ export class ShareAttributeRequestItemProcessor extends GenericRequestItemProces
if (nonPendingRelationshipsToPeer.length === 0) {
return ValidationResult.error(ConsumptionCoreErrors.requests.cannotShareRelationshipAttributeOfPendingRelationship());
}

if (recipient && !foundAttribute.shareInfo.peer.equals(recipient) && !requestItem.thirdPartyAddress) {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(
"The source attribute provided is a relationship attribute. You must provide a third party address that is the original peer when sharing with a third party."
)
);
}

if (requestItem.thirdPartyAddress && !requestItem.thirdPartyAddress.equals(foundAttribute.shareInfo.peer)) {
return ValidationResult.error(new CoreError("The third party address must be the peer of the relationship attribute."));
}
}

if (requestItem.attribute instanceof IdentityAttribute) {
Expand Down Expand Up @@ -172,7 +184,8 @@ export class ShareAttributeRequestItemProcessor extends GenericRequestItemProces
const localAttribute = await this.consumptionController.attributes.createSharedLocalAttribute({
content: requestItem.attribute,
peer: requestInfo.peer,
requestReference: requestInfo.id
requestReference: requestInfo.id,
thirdPartyAddress: requestItem.thirdPartyAddress
});

return ShareAttributeAcceptResponseItem.from({
Expand All @@ -194,7 +207,8 @@ export class ShareAttributeRequestItemProcessor extends GenericRequestItemProces
attributeId: responseItem.attributeId,
sourceAttributeId: requestItem.sourceAttributeId,
peer: requestInfo.peer,
requestReference: requestInfo.id
requestReference: requestInfo.id,
thirdPartyAddress: requestItem.thirdPartyAddress
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,27 +138,32 @@ describe("ShareAttributeRequestItemProcessor", function () {
const sender = testAccount.identity.address;
const recipient = CoreAddress.from("Recipient");

// eslint-disable-next-line jest/no-conditional-in-test
if (testParams.attribute.owner.address === "Sender") {
testParams.attribute.owner = sender;
}

// eslint-disable-next-line jest/no-conditional-in-test
if (testParams.attribute.owner.address === "Recipient") {
testParams.attribute.owner = recipient;
}

let sourceAttribute;

// eslint-disable-next-line jest/no-conditional-in-test
if (testParams.attribute instanceof IdentityAttribute) {
sourceAttribute = await consumptionController.attributes.createAttributeUnsafe({
content: {
...testParams.attribute.toJSON(),
// eslint-disable-next-line jest/no-conditional-in-test
owner: testParams.attribute.owner.equals("") ? sender : testParams.attribute.owner
} as IIdentityAttribute
});
} else {
sourceAttribute = await consumptionController.attributes.createSharedLocalAttribute({
content: {
...testParams.attribute.toJSON(),
// eslint-disable-next-line jest/no-conditional-in-test
owner: testParams.attribute.owner.equals("") ? sender : testParams.attribute.owner
} as IRelationshipAttribute,
peer: aThirdParty,
Expand All @@ -169,12 +174,14 @@ describe("ShareAttributeRequestItemProcessor", function () {
const requestItem = ShareAttributeRequestItem.from({
mustBeAccepted: false,
attribute: sourceAttribute.content,
sourceAttributeId: sourceAttribute.id
sourceAttributeId: sourceAttribute.id,
thirdPartyAddress: aThirdParty
});
const request = Request.from({ items: [requestItem] });

const result = await processor.canCreateOutgoingRequestItem(requestItem, request, recipient);

// eslint-disable-next-line jest/no-conditional-in-test
if (testParams.result === "success") {
// eslint-disable-next-line jest/no-conditional-expect
expect(result).successfulValidationResult();
Expand Down Expand Up @@ -861,7 +868,8 @@ describe("ShareAttributeRequestItemProcessor", function () {
const requestItem = ShareAttributeRequestItem.from({
mustBeAccepted: false,
attribute: initialRelationshipAttribute.content,
sourceAttributeId: initialRelationshipAttribute.id
sourceAttributeId: initialRelationshipAttribute.id,
thirdPartyAddress: aThirdParty
});
const request = Request.from({ items: [requestItem] });

Expand Down Expand Up @@ -908,7 +916,8 @@ describe("ShareAttributeRequestItemProcessor", function () {
const requestItem = ShareAttributeRequestItem.from({
mustBeAccepted: false,
attribute: initialRelationshipAttribute.content,
sourceAttributeId: initialRelationshipAttribute.id
sourceAttributeId: initialRelationshipAttribute.id,
thirdPartyAddress: aThirdParty
});
const request = Request.from({ items: [requestItem] });

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { serialize, type, validate } from "@js-soft/ts-serval";
import { CoreId, ICoreId } from "@nmshd/core-types";
import { CoreAddress, CoreId, ICoreId } from "@nmshd/core-types";
import { IdentityAttribute, IdentityAttributeJSON, IIdentityAttribute, IRelationshipAttribute, RelationshipAttribute, RelationshipAttributeJSON } from "../../../attributes";
import { AcceptResponseItem, AcceptResponseItemJSON, IAcceptResponseItem } from "../../response";

export interface ReadAttributeAcceptResponseItemJSON extends AcceptResponseItemJSON {
"@type": "ReadAttributeAcceptResponseItem";
attributeId: string;
attribute: IdentityAttributeJSON | RelationshipAttributeJSON;
thirdPartyAddress?: string;
}

export interface IReadAttributeAcceptResponseItem extends IAcceptResponseItem {
attributeId: ICoreId;
attribute: IIdentityAttribute | IRelationshipAttribute;
thirdPartyAddress?: CoreAddress;
}

@type("ReadAttributeAcceptResponseItem")
Expand All @@ -24,6 +26,10 @@ export class ReadAttributeAcceptResponseItem extends AcceptResponseItem implemen
@validate()
public attribute: IdentityAttribute | RelationshipAttribute;

@serialize()
@validate({ nullable: true })
public thirdPartyAddress?: CoreAddress;

public static override from(
value: IReadAttributeAcceptResponseItem | Omit<ReadAttributeAcceptResponseItemJSON, "@type"> | ReadAttributeAcceptResponseItemJSON
): ReadAttributeAcceptResponseItem {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { serialize, type, validate } from "@js-soft/ts-serval";
import { CoreId, ICoreId } from "@nmshd/core-types";
import { CoreAddress, CoreId, ICoreId } from "@nmshd/core-types";
import { RequestItemJSON } from "../..";
import { IdentityAttribute, IdentityAttributeJSON, IIdentityAttribute, IRelationshipAttribute, RelationshipAttribute, RelationshipAttributeJSON } from "../../../attributes";
import { IRequestItem, RequestItem } from "../../RequestItem";
Expand All @@ -8,11 +8,13 @@ export interface ShareAttributeRequestItemJSON extends RequestItemJSON {
"@type": "ShareAttributeRequestItem";
attribute: IdentityAttributeJSON | RelationshipAttributeJSON;
sourceAttributeId: string;
thirdPartyAddress?: string;
}

export interface IShareAttributeRequestItem extends IRequestItem {
attribute: IIdentityAttribute | IRelationshipAttribute;
sourceAttributeId: ICoreId;
thirdPartyAddress?: CoreAddress;
}

@type("ShareAttributeRequestItem")
Expand All @@ -25,6 +27,10 @@ export class ShareAttributeRequestItem extends RequestItem implements IShareAttr
@validate()
public sourceAttributeId: CoreId;

@serialize()
@validate({ nullable: true })
public thirdPartyAddress?: CoreAddress;

public static from(value: IShareAttributeRequestItem | Omit<ShareAttributeRequestItemJSON, "@type"> | ShareAttributeRequestItemJSON): ShareAttributeRequestItem {
return this.fromAny(value);
}
Expand Down
4 changes: 4 additions & 0 deletions packages/runtime/src/modules/AttributeListenerModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ export class AttributeListenerModule extends RuntimeModule {
metadata: { attributeListenerId: attributeListener.id }
};

if (attribute.content["@type"] === "RelationshipAttribute" && attributeListener.peer !== attribute.shareInfo?.peer) {
requestItem.thirdPartyAddress = attribute.shareInfo?.peer;
}

const validationResult = await services.consumptionServices.outgoingRequests.canCreate({
content: { items: [requestItem] },
peer: attributeListener.peer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface LocalAttributeShareInfoDTO {
notificationReference?: string;
peer: string;
sourceAttribute?: string;
thirdPartyAddress?: string;
}

export enum LocalAttributeDeletionStatus {
Expand Down
Loading