Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -8,7 +8,7 @@ import {
TransferFileOwnershipAcceptResponseItem,
TransferFileOwnershipRequestItem
} from "@nmshd/content";
import { CoreAddress, CoreDate, CoreId } from "@nmshd/core-types";
import { CoreAddress, CoreId } from "@nmshd/core-types";
import { File } from "@nmshd/transport";
import { ConsumptionCoreErrors } from "../../../../consumption/ConsumptionCoreErrors";
import { ValidationResult } from "../../../common/ValidationResult";
Expand Down Expand Up @@ -53,15 +53,11 @@ export class TransferFileOwnershipRequestItemProcessor extends GenericRequestIte
}
}

if (requestItem.ownershipToken) {
const validationResult = await this.accountController.files.validateFileOwnershipToken(foundFile.id, requestItem.ownershipToken);
if (!validationResult.isValid) {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(
`The specified ownershipToken is not valid for the File with ID '${requestItem.fileReference.id.toString()}'.`
)
);
}
const validationResult = await this.accountController.files.validateFileOwnershipToken(foundFile.id, requestItem.ownershipToken);
if (!validationResult.isValid) {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(`The specified ownershipToken is not valid for the File with ID '${requestItem.fileReference.id.toString()}'.`)
);
}

return ValidationResult.success();
Expand Down Expand Up @@ -118,15 +114,13 @@ export class TransferFileOwnershipRequestItemProcessor extends GenericRequestIte
}
}

if (requestItem.ownershipToken) {
const validationResult = await this.accountController.files.validateFileOwnershipToken(file.id, requestItem.ownershipToken);
if (!validationResult.isValid) {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(
`You cannot accept this RequestItem since the specified ownershipToken is not valid for the File with ID '${requestItem.fileReference.id.toString()}'.`
)
);
}
const validationResult = await this.accountController.files.validateFileOwnershipToken(file.id, requestItem.ownershipToken);
if (!validationResult.isValid) {
return ValidationResult.error(
ConsumptionCoreErrors.requests.invalidRequestItem(
`You cannot accept this RequestItem since the specified ownershipToken is not valid for the File with ID '${requestItem.fileReference.id.toString()}'.`
)
);
}

return ValidationResult.success();
Expand All @@ -139,9 +133,7 @@ export class TransferFileOwnershipRequestItemProcessor extends GenericRequestIte
): Promise<TransferFileOwnershipAcceptResponseItem> {
const peerFile = await this.accountController.files.getOrLoadFileByReference(requestItem.fileReference);

const ownFile = requestItem.ownershipToken
? await this.accountController.files.claimFileOwnership(peerFile.id, requestItem.ownershipToken)
: await this.transferFileOwnershipByReupload(peerFile);
const ownFile = await this.accountController.files.claimFileOwnership(peerFile.id, requestItem.ownershipToken);

const repositoryAttribute = await this.consumptionController.attributes.createRepositoryAttribute({
content: IdentityAttribute.from({
Expand All @@ -166,19 +158,6 @@ export class TransferFileOwnershipRequestItemProcessor extends GenericRequestIte
});
}

private async transferFileOwnershipByReupload(peerFile: File) {
const fileContent = await this.accountController.files.downloadFileContent(peerFile);
return await this.accountController.files.sendFile({
buffer: fileContent,
title: peerFile.cache!.title,
description: peerFile.cache!.description,
filename: peerFile.cache!.filename,
mimetype: peerFile.cache!.mimetype,
expiresAt: CoreDate.from("9999-12-31T00:00:00.000Z"),
tags: peerFile.cache!.tags
});
}

public override async applyIncomingResponseItem(
responseItem: TransferFileOwnershipAcceptResponseItem | AcceptResponseItem | RejectResponseItem,
_requestItem: TransferFileOwnershipRequestItem,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IDatabaseConnection } from "@js-soft/docdb-access-abstractions";
import { sleep } from "@js-soft/ts-utils";
import { IdentityAttribute, IdentityFileReference, Request, ResponseItemResult, TransferFileOwnershipAcceptResponseItem, TransferFileOwnershipRequestItem } from "@nmshd/content";
import { CoreAddress, CoreDate, FileReference } from "@nmshd/core-types";
import { CoreAddress, CoreDate } from "@nmshd/core-types";
import { AccountController } from "@nmshd/transport";
import { ConsumptionController, ConsumptionIds, LocalRequest, LocalRequestStatus, TransferFileOwnershipRequestItemProcessor } from "../../../../../src";
import { TestUtil } from "../../../../core/TestUtil";
Expand Down Expand Up @@ -51,7 +51,8 @@ describe("TransferFileOwnershipRequestItemProcessor", function () {

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: senderFile.toFileReference(senderAccountController.config.baseUrl).truncate()
fileReference: senderFile.toFileReference(senderAccountController.config.baseUrl).truncate(),
ownershipToken: senderFile.ownershipToken!
});
const request = Request.from({ items: [requestItem] });

Expand All @@ -62,23 +63,10 @@ describe("TransferFileOwnershipRequestItemProcessor", function () {
test("returns success if the ownership of an own File should be transferred entering a FileReference", async function () {
const senderFile = await TestUtil.uploadFile(senderAccountController, { tags: ["x:tag"] });

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: senderFile.toFileReference(senderAccountController.config.baseUrl)
});
const request = Request.from({ items: [requestItem] });

const result = await senderProcessor.canCreateOutgoingRequestItem(requestItem, request, recipient);
expect(result).successfulValidationResult();
});

test("returns success if the ownership of an own File should be transferred using an ownershipToken", async function () {
const senderFile = await TestUtil.uploadFile(senderAccountController, { tags: ["x:tag"] });

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: senderFile.toFileReference(senderAccountController.config.baseUrl),
ownershipToken: senderFile.ownershipToken
ownershipToken: senderFile.ownershipToken!
});
const request = Request.from({ items: [requestItem] });

Expand All @@ -91,7 +79,8 @@ describe("TransferFileOwnershipRequestItemProcessor", function () {

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: thirdPartyFile.toFileReference(thirdPartyAccountController.config.baseUrl)
fileReference: thirdPartyFile.toFileReference(thirdPartyAccountController.config.baseUrl),
ownershipToken: thirdPartyFile.ownershipToken!
});
const request = Request.from({ items: [requestItem] });

Expand All @@ -109,7 +98,8 @@ describe("TransferFileOwnershipRequestItemProcessor", function () {

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: thirdPartyFileReference
fileReference: thirdPartyFileReference,
ownershipToken: thirdPartyFile.ownershipToken!
});
const request = Request.from({ items: [requestItem] });

Expand All @@ -126,7 +116,8 @@ describe("TransferFileOwnershipRequestItemProcessor", function () {

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: senderExpiredFile.toFileReference(senderAccountController.config.baseUrl)
fileReference: senderExpiredFile.toFileReference(senderAccountController.config.baseUrl),
ownershipToken: senderExpiredFile.ownershipToken!
});
const request = Request.from({ items: [requestItem] });

Expand Down Expand Up @@ -159,32 +150,10 @@ describe("TransferFileOwnershipRequestItemProcessor", function () {
test("returns success when checking if the transfer of ownership of a File can be accepted that is owned by the sender", async function () {
const senderFile = await TestUtil.uploadFile(senderAccountController, { tags: ["x:tag"] });

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: senderFile.toFileReference(senderAccountController.config.baseUrl)
});

const incomingRequest = LocalRequest.from({
id: await ConsumptionIds.request.generate(),
createdAt: CoreDate.utc(),
isOwn: false,
peer: sender,
status: LocalRequestStatus.DecisionRequired,
content: Request.from({ items: [requestItem] }),
statusLog: []
});

const result = await recipientProcessor.canAccept(requestItem, { accept: true }, incomingRequest);
expect(result).successfulValidationResult();
});

test("returns success when checking if the transfer of ownership of a File can be accepted with an ownershipToken", async function () {
const senderFile = await TestUtil.uploadFile(senderAccountController, { tags: ["x:tag"] });

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: senderFile.toFileReference(senderAccountController.config.baseUrl),
ownershipToken: senderFile.ownershipToken
ownershipToken: senderFile.ownershipToken!
});

const incomingRequest = LocalRequest.from({
Expand All @@ -207,7 +176,8 @@ describe("TransferFileOwnershipRequestItemProcessor", function () {

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: senderExpiredFile.toFileReference(senderAccountController.config.baseUrl)
fileReference: senderExpiredFile.toFileReference(senderAccountController.config.baseUrl),
ownershipToken: senderExpiredFile.ownershipToken!
});

const incomingRequest = LocalRequest.from({
Expand All @@ -232,7 +202,8 @@ describe("TransferFileOwnershipRequestItemProcessor", function () {

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: recipientFile.toFileReference(recipientAccountController.config.baseUrl)
fileReference: recipientFile.toFileReference(recipientAccountController.config.baseUrl),
ownershipToken: recipientFile.ownershipToken!
});

const incomingRequest = LocalRequest.from({
Expand All @@ -257,7 +228,8 @@ describe("TransferFileOwnershipRequestItemProcessor", function () {

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: thirdPartyFile.toFileReference(thirdPartyAccountController.config.baseUrl)
fileReference: thirdPartyFile.toFileReference(thirdPartyAccountController.config.baseUrl),
ownershipToken: thirdPartyFile.ownershipToken!
});

const incomingRequest = LocalRequest.from({
Expand Down Expand Up @@ -305,52 +277,14 @@ describe("TransferFileOwnershipRequestItemProcessor", function () {
});

describe("accept", function () {
test("creates a RepositoryAttribute with tags and an own shared IdentityAttribute and responds with a TransferFileOwnershipAcceptResponseItem", async function () {
const senderFile = await TestUtil.uploadFile(senderAccountController, { tags: ["x:tag"] });

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: senderFile.toFileReference(senderAccountController.config.baseUrl)
});

const incomingRequest = LocalRequest.from({
id: await ConsumptionIds.request.generate(),
createdAt: CoreDate.utc(),
isOwn: false,
peer: sender,
status: LocalRequestStatus.DecisionRequired,
content: Request.from({ items: [requestItem] }),
statusLog: []
});

const responseItem = await recipientProcessor.accept(requestItem, { accept: true }, incomingRequest);
expect(responseItem).toBeInstanceOf(TransferFileOwnershipAcceptResponseItem);

const ownSharedIdentityAttribute = await recipientConsumptionController.attributes.getLocalAttribute(responseItem.attributeId);
expect(ownSharedIdentityAttribute!.shareInfo!.peer).toStrictEqual(sender);
expect(ownSharedIdentityAttribute!.shareInfo!.requestReference).toStrictEqual(incomingRequest.id);
expect(ownSharedIdentityAttribute!.content.value).toBeInstanceOf(IdentityFileReference);
expect((ownSharedIdentityAttribute!.content as IdentityAttribute).tags).toStrictEqual(["x:tag"]);

const repositoryAttribute = await recipientConsumptionController.attributes.getLocalAttribute(ownSharedIdentityAttribute!.shareInfo!.sourceAttribute!);
expect(repositoryAttribute!.shareInfo).toBeUndefined();
expect(repositoryAttribute!.content.value).toBeInstanceOf(IdentityFileReference);
expect((repositoryAttribute!.content as IdentityAttribute).tags).toStrictEqual(["x:tag"]);

const fileReference = FileReference.from((repositoryAttribute!.content.value as IdentityFileReference).value);
const file = await recipientAccountController.files.getFile(fileReference.id);
expect(file!.isOwn).toBe(true);
expect(file!.cache!.tags).toStrictEqual(["x:tag"]);
Comment thread
Milena-Czierlinski marked this conversation as resolved.
});

test("claims the ownership of the sender's file", async function () {
test("should accept a TransferFileOwnershipRequestItem", async function () {
const senderFile = await TestUtil.uploadFile(senderAccountController, { tags: ["x:tag"] });
const senderFileReference = senderFile.toFileReference(senderAccountController.config.baseUrl);

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: senderFileReference,
ownershipToken: senderFile.ownershipToken
ownershipToken: senderFile.ownershipToken!
});

const incomingRequest = LocalRequest.from({
Expand Down Expand Up @@ -387,53 +321,14 @@ describe("TransferFileOwnershipRequestItemProcessor", function () {
});

describe("applyIncomingResponseItem", function () {
test("creates peer shared IdentityAttribute in case of a TransferFileOwnershipAcceptResponseItem", async function () {
const senderFile = await TestUtil.uploadFile(senderAccountController, { tags: ["x:tag"] });

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: senderFile.toFileReference(senderAccountController.config.baseUrl)
});

const requestInfo = {
id: await ConsumptionIds.request.generate(),
peer: recipient
};

const recipientFile = await TestUtil.uploadFile(recipientAccountController, { tags: ["x:tag"] });
const responseItem = TransferFileOwnershipAcceptResponseItem.from({
result: ResponseItemResult.Accepted,
attributeId: await ConsumptionIds.attribute.generate(),
attribute: IdentityAttribute.from({
value: IdentityFileReference.from({
value: recipientFile.toFileReference(recipientAccountController.config.baseUrl).truncate()
}),
owner: recipient,
tags: ["x:tag"]
})
});

await senderProcessor.applyIncomingResponseItem(responseItem, requestItem, requestInfo);

const peerSharedIdentityAttribute = await senderConsumptionController.attributes.getLocalAttribute(responseItem.attributeId);
expect(peerSharedIdentityAttribute!.shareInfo!.peer).toStrictEqual(recipient);
expect(peerSharedIdentityAttribute!.shareInfo!.requestReference).toStrictEqual(requestInfo.id);
expect(peerSharedIdentityAttribute!.shareInfo!.sourceAttribute).toBeUndefined();

const truncatedFileReference = (peerSharedIdentityAttribute!.content.value as IdentityFileReference).value;
const file = await senderAccountController.files.getOrLoadFileByReference(FileReference.from(truncatedFileReference));
expect(file.isOwn).toBe(false);
expect(file.cache!.tags).toStrictEqual(["x:tag"]);
Comment thread
Milena-Czierlinski marked this conversation as resolved.
});

test("updates the File whose ownership was claimed", async function () {
test("should update the File whose ownership was claimed", async function () {
const senderFile = await TestUtil.uploadFile(senderAccountController, { tags: ["x:tag"] });
const senderTruncatedFileReference = senderFile.toFileReference(senderAccountController.config.baseUrl).truncate();

const requestItem = TransferFileOwnershipRequestItem.from({
mustBeAccepted: false,
fileReference: senderTruncatedFileReference,
ownershipToken: senderFile.ownershipToken
ownershipToken: senderFile.ownershipToken!
});

const requestInfo = {
Expand Down Expand Up @@ -467,6 +362,7 @@ describe("TransferFileOwnershipRequestItemProcessor", function () {
expect(peerSharedIdentityAttribute!.shareInfo!.peer).toStrictEqual(recipient);
expect(peerSharedIdentityAttribute!.shareInfo!.requestReference).toStrictEqual(requestInfo.id);
expect(peerSharedIdentityAttribute!.shareInfo!.sourceAttribute).toBeUndefined();
expect((peerSharedIdentityAttribute!.content as IdentityAttribute).tags).toStrictEqual(["x:tag"]);

const peerTruncatedFileReference = (peerSharedIdentityAttribute!.content.value as IdentityFileReference).value;
expect(peerTruncatedFileReference).toStrictEqual(senderTruncatedFileReference);
Expand Down
Loading