diff --git a/package-lock.json b/package-lock.json index 994af96a4..8fcd0aa73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,13 +18,13 @@ "@js-soft/eslint-config-ts": "^1.6.9", "@js-soft/license-check": "^1.0.9", "@types/jest": "^29.5.13", - "@types/node": "^22.5.5", + "@types/node": "^22.6.0", "enhanced-publish": "^1.1.3", "eslint": "^8.57.1", "jest": "^29.7.0", "jest-expect-message": "^1.1.3", "madge": "^8.0.0", - "npm-check-updates": "^17.1.1", + "npm-check-updates": "^17.1.3", "prettier": "^3.3.3", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", @@ -2137,9 +2137,9 @@ "license": "MIT" }, "node_modules/@types/lodash": { - "version": "4.17.7", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", - "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", + "version": "4.17.9", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.9.tgz", + "integrity": "sha512-w9iWudx1XWOHW5lQRS9iKpK/XuRhnN+0T7HvdCCd802FYkT1AMTnxndJHGrNJwRoRHkslGr4S29tjm1cT7x/7w==", "dev": true }, "node_modules/@types/lokijs": { @@ -2154,9 +2154,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.5.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", - "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", + "version": "22.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.6.0.tgz", + "integrity": "sha512-QyR8d5bmq+eR72TwQDfujwShHMcIrWIYsaQFtXRE58MHPTEKUNxjxvl0yS0qPMds5xbSDWtp7ZpvGFtd7dfMdQ==", "dev": true, "dependencies": { "undici-types": "~6.19.2" @@ -6575,9 +6575,9 @@ } }, "node_modules/npm-check-updates": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-17.1.1.tgz", - "integrity": "sha512-2aqIzGAEWB7xPf0hKHTkNmUM5jHbn2S5r2/z/7dA5Ij2h/sVYAg9R/uVkaUC3VORPAfBm7pKkCWo6E9clEVQ9A==", + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-17.1.3.tgz", + "integrity": "sha512-4uDLBWPuDHT5KLieIJ20FoAB8yqJejmupI42wPyfObgQOBbPAikQSwT73afDwREvhuxYrRDqlRvxTMSfvO+L8A==", "dev": true, "bin": { "ncu": "build/cli.js", @@ -9312,7 +9312,7 @@ }, "devDependencies": { "@js-soft/web-logger": "^1.0.4", - "@types/lodash": "^4.17.7", + "@types/lodash": "^4.17.9", "@types/lokijs": "^1.5.14", "@types/luxon": "^3.4.2" } @@ -9336,7 +9336,7 @@ "@js-soft/docdb-access-mongo": "1.1.9", "@js-soft/node-logger": "1.2.0", "@nmshd/crypto": "2.0.6", - "@types/lodash": "^4.17.7" + "@types/lodash": "^4.17.9" } }, "packages/content": { @@ -9396,7 +9396,7 @@ "@js-soft/docdb-access-mongo": "1.1.9", "@js-soft/node-logger": "1.2.0", "@types/json-stringify-safe": "^5.0.3", - "@types/lodash": "^4.17.7", + "@types/lodash": "^4.17.9", "@types/luxon": "^3.4.2", "@types/qrcode": "^1.5.5", "ts-json-schema-generator": "2.3.0" @@ -9437,7 +9437,7 @@ "@js-soft/node-logger": "1.2.0", "@js-soft/ts-serval": "2.0.11", "@types/json-stringify-safe": "^5.0.3", - "@types/lodash": "^4.17.7", + "@types/lodash": "^4.17.9", "@types/luxon": "^3.4.2", "@types/qs": "^6.9.16", "@types/uuid": "^10.0.0", diff --git a/package.json b/package.json index 2afce8bb0..66e043a85 100644 --- a/package.json +++ b/package.json @@ -30,13 +30,13 @@ "@js-soft/eslint-config-ts": "^1.6.9", "@js-soft/license-check": "^1.0.9", "@types/jest": "^29.5.13", - "@types/node": "^22.5.5", + "@types/node": "^22.6.0", "enhanced-publish": "^1.1.3", "eslint": "^8.57.1", "jest": "^29.7.0", "jest-expect-message": "^1.1.3", "madge": "^8.0.0", - "npm-check-updates": "^17.1.1", + "npm-check-updates": "^17.1.3", "prettier": "^3.3.3", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", diff --git a/packages/app-runtime/package.json b/packages/app-runtime/package.json index 17294ca5f..67c12d385 100644 --- a/packages/app-runtime/package.json +++ b/packages/app-runtime/package.json @@ -57,7 +57,7 @@ }, "devDependencies": { "@js-soft/web-logger": "^1.0.4", - "@types/lodash": "^4.17.7", + "@types/lodash": "^4.17.9", "@types/lokijs": "^1.5.14", "@types/luxon": "^3.4.2" }, diff --git a/packages/app-runtime/src/AppStringProcessor.ts b/packages/app-runtime/src/AppStringProcessor.ts index 7f8fabd52..c8ed7d334 100644 --- a/packages/app-runtime/src/AppStringProcessor.ts +++ b/packages/app-runtime/src/AppStringProcessor.ts @@ -63,9 +63,7 @@ export class AppStringProcessor { return UserfriendlyResult.fail(error); } - const tokenResult = await this.runtime.anonymousServices.tokens.loadPeerTokenByTruncatedReference({ - reference: truncatedReference - }); + const tokenResult = await this.runtime.anonymousServices.tokens.loadPeerToken({ reference: truncatedReference }); if (tokenResult.isError) { return UserfriendlyResult.fail(UserfriendlyApplicationError.fromError(tokenResult.error)); } diff --git a/packages/consumption/package.json b/packages/consumption/package.json index 922e32e70..be83b421a 100644 --- a/packages/consumption/package.json +++ b/packages/consumption/package.json @@ -74,7 +74,7 @@ "@js-soft/docdb-access-mongo": "1.1.9", "@js-soft/node-logger": "1.2.0", "@nmshd/crypto": "2.0.6", - "@types/lodash": "^4.17.7" + "@types/lodash": "^4.17.9" }, "publishConfig": { "access": "public", diff --git a/packages/runtime/package.json b/packages/runtime/package.json index bf09533bb..df66ea3e3 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -86,7 +86,7 @@ "@js-soft/docdb-access-mongo": "1.1.9", "@js-soft/node-logger": "1.2.0", "@types/json-stringify-safe": "^5.0.3", - "@types/lodash": "^4.17.7", + "@types/lodash": "^4.17.9", "@types/luxon": "^3.4.2", "@types/qrcode": "^1.5.5", "ts-json-schema-generator": "2.3.0" diff --git a/packages/runtime/src/dataViews/transport/FileDVO.ts b/packages/runtime/src/dataViews/transport/FileDVO.ts index a20643141..15c5f6722 100644 --- a/packages/runtime/src/dataViews/transport/FileDVO.ts +++ b/packages/runtime/src/dataViews/transport/FileDVO.ts @@ -12,6 +12,5 @@ export interface FileDVO extends DataViewObject { mimetype: string; isOwn: boolean; title: string; - secretKey: string; truncatedReference: string; } diff --git a/packages/runtime/src/extensibility/facades/anonymous/AnonymousTokensFacade.ts b/packages/runtime/src/extensibility/facades/anonymous/AnonymousTokensFacade.ts index a5c57353a..088fc82a0 100644 --- a/packages/runtime/src/extensibility/facades/anonymous/AnonymousTokensFacade.ts +++ b/packages/runtime/src/extensibility/facades/anonymous/AnonymousTokensFacade.ts @@ -1,24 +1,12 @@ import { ApplicationError, Result } from "@js-soft/ts-utils"; import { Inject } from "typescript-ioc"; import { TokenDTO } from "../../../types"; -import { - LoadPeerTokenAnonymousByIdAndKeyRequest, - LoadPeerTokenAnonymousByIdAndKeyUseCase, - LoadPeerTokenAnonymousByTruncatedReferenceRequest, - LoadPeerTokenAnonymousByTruncatedReferenceUseCase -} from "../../../useCases"; +import { LoadPeerTokenAnonymousRequest, LoadPeerTokenAnonymousUseCase } from "../../../useCases"; export class AnonymousTokensFacade { - public constructor( - @Inject private readonly loadPeerTokenByTruncatedReferenceUseCase: LoadPeerTokenAnonymousByTruncatedReferenceUseCase, - @Inject private readonly loadPeerTokenByIdAndKeyUseCase: LoadPeerTokenAnonymousByIdAndKeyUseCase - ) {} + public constructor(@Inject private readonly loadPeerTokenUseCase: LoadPeerTokenAnonymousUseCase) {} - public async loadPeerTokenByTruncatedReference(request: LoadPeerTokenAnonymousByTruncatedReferenceRequest): Promise> { - return await this.loadPeerTokenByTruncatedReferenceUseCase.execute(request); - } - - public async loadPeerTokenByIdAndKey(request: LoadPeerTokenAnonymousByIdAndKeyRequest): Promise> { - return await this.loadPeerTokenByIdAndKeyUseCase.execute(request); + public async loadPeerToken(request: LoadPeerTokenAnonymousRequest): Promise> { + return await this.loadPeerTokenUseCase.execute(request); } } diff --git a/packages/runtime/src/types/transport/FileDTO.ts b/packages/runtime/src/types/transport/FileDTO.ts index 0151489ce..7006b6498 100644 --- a/packages/runtime/src/types/transport/FileDTO.ts +++ b/packages/runtime/src/types/transport/FileDTO.ts @@ -9,7 +9,6 @@ export interface FileDTO { mimetype: string; isOwn: boolean; title: string; - secretKey: string; description?: string; truncatedReference: string; } diff --git a/packages/runtime/src/types/transport/RelationshipTemplateDTO.ts b/packages/runtime/src/types/transport/RelationshipTemplateDTO.ts index 3b5f1a6a2..1a6f3cb02 100644 --- a/packages/runtime/src/types/transport/RelationshipTemplateDTO.ts +++ b/packages/runtime/src/types/transport/RelationshipTemplateDTO.ts @@ -11,6 +11,5 @@ export interface RelationshipTemplateDTO { content: RelationshipTemplateContentDerivation; expiresAt?: string; maxNumberOfAllocations?: number; - secretKey: string; truncatedReference: string; } diff --git a/packages/runtime/src/types/transport/TokenDTO.ts b/packages/runtime/src/types/transport/TokenDTO.ts index 4eca98d39..a83ac83d4 100644 --- a/packages/runtime/src/types/transport/TokenDTO.ts +++ b/packages/runtime/src/types/transport/TokenDTO.ts @@ -5,7 +5,6 @@ export interface TokenDTO { content: any; createdAt: string; expiresAt: string; - secretKey: string; truncatedReference: string; isEphemeral: boolean; } diff --git a/packages/runtime/src/useCases/anonymous/tokens/LoadPeerTokenAnonymousByTruncatedReference.ts b/packages/runtime/src/useCases/anonymous/tokens/LoadPeerTokenAnonymous.ts similarity index 71% rename from packages/runtime/src/useCases/anonymous/tokens/LoadPeerTokenAnonymousByTruncatedReference.ts rename to packages/runtime/src/useCases/anonymous/tokens/LoadPeerTokenAnonymous.ts index 108ebab54..3eec7c492 100644 --- a/packages/runtime/src/useCases/anonymous/tokens/LoadPeerTokenAnonymousByTruncatedReference.ts +++ b/packages/runtime/src/useCases/anonymous/tokens/LoadPeerTokenAnonymous.ts @@ -5,17 +5,17 @@ import { TokenDTO } from "../../../types"; import { SchemaRepository, SchemaValidator, TokenReferenceString, UseCase } from "../../common"; import { TokenMapper } from "../../transport/tokens/TokenMapper"; -export interface LoadPeerTokenAnonymousByTruncatedReferenceRequest { +export interface LoadPeerTokenAnonymousRequest { reference: TokenReferenceString; } -class Validator extends SchemaValidator { +class Validator extends SchemaValidator { public constructor(@Inject schemaRepository: SchemaRepository) { - super(schemaRepository.getSchema("LoadPeerTokenAnonymousByTruncatedReferenceRequest")); + super(schemaRepository.getSchema("LoadPeerTokenAnonymousRequest")); } } -export class LoadPeerTokenAnonymousByTruncatedReferenceUseCase extends UseCase { +export class LoadPeerTokenAnonymousUseCase extends UseCase { public constructor( @Inject private readonly anonymousTokenController: AnonymousTokenController, @Inject validator: Validator @@ -23,7 +23,7 @@ export class LoadPeerTokenAnonymousByTruncatedReferenceUseCase extends UseCase> { + protected async executeInternal(request: LoadPeerTokenAnonymousRequest): Promise> { const createdToken = await this.anonymousTokenController.loadPeerTokenByTruncated(request.reference); return Result.ok(TokenMapper.toTokenDTO(createdToken, true)); } diff --git a/packages/runtime/src/useCases/anonymous/tokens/LoadPeerTokenAnonymousByIdAndKey.ts b/packages/runtime/src/useCases/anonymous/tokens/LoadPeerTokenAnonymousByIdAndKey.ts deleted file mode 100644 index 65e853332..000000000 --- a/packages/runtime/src/useCases/anonymous/tokens/LoadPeerTokenAnonymousByIdAndKey.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Result } from "@js-soft/ts-utils"; -import { CoreId } from "@nmshd/core-types"; -import { CryptoSecretKey } from "@nmshd/crypto"; -import { AnonymousTokenController } from "@nmshd/transport"; -import { Inject } from "typescript-ioc"; -import { TokenDTO } from "../../../types"; -import { SchemaRepository, SchemaValidator, TokenIdString, UseCase } from "../../common"; -import { TokenMapper } from "../../transport/tokens/TokenMapper"; - -export interface LoadPeerTokenAnonymousByIdAndKeyRequest { - id: TokenIdString; - secretKey: string; -} - -class Validator extends SchemaValidator { - public constructor(@Inject schemaRepository: SchemaRepository) { - super(schemaRepository.getSchema("LoadPeerTokenAnonymousByIdAndKeyRequest")); - } -} - -export class LoadPeerTokenAnonymousByIdAndKeyUseCase extends UseCase { - public constructor( - @Inject private readonly anonymousTokenController: AnonymousTokenController, - @Inject validator: Validator - ) { - super(validator); - } - - protected async executeInternal(request: LoadPeerTokenAnonymousByIdAndKeyRequest): Promise> { - const key = CryptoSecretKey.fromBase64(request.secretKey); - const createdToken = await this.anonymousTokenController.loadPeerToken(CoreId.from(request.id), key); - - return Result.ok(TokenMapper.toTokenDTO(createdToken, true)); - } -} diff --git a/packages/runtime/src/useCases/anonymous/tokens/index.ts b/packages/runtime/src/useCases/anonymous/tokens/index.ts index d934aa8f0..795bfa08f 100644 --- a/packages/runtime/src/useCases/anonymous/tokens/index.ts +++ b/packages/runtime/src/useCases/anonymous/tokens/index.ts @@ -1,2 +1 @@ -export * from "./LoadPeerTokenAnonymousByIdAndKey"; -export * from "./LoadPeerTokenAnonymousByTruncatedReference"; +export * from "./LoadPeerTokenAnonymous"; diff --git a/packages/runtime/src/useCases/common/Schemas.ts b/packages/runtime/src/useCases/common/Schemas.ts index 42537be14..fdf631b6a 100644 --- a/packages/runtime/src/useCases/common/Schemas.ts +++ b/packages/runtime/src/useCases/common/Schemas.ts @@ -1,35 +1,8 @@ -export const LoadPeerTokenAnonymousByIdAndKeyRequest: any = { +export const LoadPeerTokenAnonymousRequest: any = { "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/definitions/LoadPeerTokenAnonymousByIdAndKeyRequest", + "$ref": "#/definitions/LoadPeerTokenAnonymousRequest", "definitions": { - "LoadPeerTokenAnonymousByIdAndKeyRequest": { - "type": "object", - "properties": { - "id": { - "$ref": "#/definitions/TokenIdString" - }, - "secretKey": { - "type": "string" - } - }, - "required": [ - "id", - "secretKey" - ], - "additionalProperties": false - }, - "TokenIdString": { - "type": "string", - "pattern": "TOK[A-Za-z0-9]{17}" - } - } -} - -export const LoadPeerTokenAnonymousByTruncatedReferenceRequest: any = { - "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/definitions/LoadPeerTokenAnonymousByTruncatedReferenceRequest", - "definitions": { - "LoadPeerTokenAnonymousByTruncatedReferenceRequest": { + "LoadPeerTokenAnonymousRequest": { "type": "object", "properties": { "reference": { @@ -21500,105 +21473,11 @@ export const GetFilesRequest: any = { } } -export const GetOrLoadFileViaSecretRequest: any = { - "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/definitions/GetOrLoadFileViaSecretRequest", - "definitions": { - "GetOrLoadFileViaSecretRequest": { - "type": "object", - "properties": { - "id": { - "$ref": "#/definitions/FileIdString" - }, - "secretKey": { - "type": "string", - "minLength": 10 - } - }, - "required": [ - "id", - "secretKey" - ], - "additionalProperties": false - }, - "FileIdString": { - "type": "string", - "pattern": "FIL[A-Za-z0-9]{17}" - } - } -} - -export const GetOrLoadFileViaReferenceRequest: any = { - "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/definitions/GetOrLoadFileViaReferenceRequest", - "definitions": { - "GetOrLoadFileViaReferenceRequest": { - "type": "object", - "properties": { - "reference": { - "anyOf": [ - { - "$ref": "#/definitions/TokenReferenceString" - }, - { - "$ref": "#/definitions/FileReferenceString" - } - ] - } - }, - "required": [ - "reference" - ], - "additionalProperties": false, - "errorMessage": "token / file reference invalid" - }, - "TokenReferenceString": { - "type": "string", - "pattern": "VE9L.{84}" - }, - "FileReferenceString": { - "type": "string", - "pattern": "RklM.{84}" - } - } -} - export const GetOrLoadFileRequest: any = { "$schema": "http://json-schema.org/draft-07/schema#", "$ref": "#/definitions/GetOrLoadFileRequest", "definitions": { "GetOrLoadFileRequest": { - "anyOf": [ - { - "$ref": "#/definitions/GetOrLoadFileViaSecretRequest" - }, - { - "$ref": "#/definitions/GetOrLoadFileViaReferenceRequest" - } - ] - }, - "GetOrLoadFileViaSecretRequest": { - "type": "object", - "properties": { - "id": { - "$ref": "#/definitions/FileIdString" - }, - "secretKey": { - "type": "string", - "minLength": 10 - } - }, - "required": [ - "id", - "secretKey" - ], - "additionalProperties": false - }, - "FileIdString": { - "type": "string", - "pattern": "FIL[A-Za-z0-9]{17}" - }, - "GetOrLoadFileViaReferenceRequest": { "type": "object", "properties": { "reference": { @@ -22304,105 +22183,11 @@ export const GetRelationshipTemplatesRequest: any = { } } -export const LoadPeerRelationshipTemplateViaSecretRequest: any = { - "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/definitions/LoadPeerRelationshipTemplateViaSecretRequest", - "definitions": { - "LoadPeerRelationshipTemplateViaSecretRequest": { - "type": "object", - "properties": { - "id": { - "$ref": "#/definitions/RelationshipTemplateIdString" - }, - "secretKey": { - "type": "string", - "minLength": 10 - } - }, - "required": [ - "id", - "secretKey" - ], - "additionalProperties": false - }, - "RelationshipTemplateIdString": { - "type": "string", - "pattern": "RLT[A-Za-z0-9]{17}" - } - } -} - -export const LoadPeerRelationshipTemplateViaReferenceRequest: any = { - "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/definitions/LoadPeerRelationshipTemplateViaReferenceRequest", - "definitions": { - "LoadPeerRelationshipTemplateViaReferenceRequest": { - "type": "object", - "properties": { - "reference": { - "anyOf": [ - { - "$ref": "#/definitions/TokenReferenceString" - }, - { - "$ref": "#/definitions/RelationshipTemplateReferenceString" - } - ] - } - }, - "required": [ - "reference" - ], - "additionalProperties": false, - "errorMessage": "token / relationship template reference invalid" - }, - "TokenReferenceString": { - "type": "string", - "pattern": "VE9L.{84}" - }, - "RelationshipTemplateReferenceString": { - "type": "string", - "pattern": "UkxU.{84}" - } - } -} - export const LoadPeerRelationshipTemplateRequest: any = { "$schema": "http://json-schema.org/draft-07/schema#", "$ref": "#/definitions/LoadPeerRelationshipTemplateRequest", "definitions": { "LoadPeerRelationshipTemplateRequest": { - "anyOf": [ - { - "$ref": "#/definitions/LoadPeerRelationshipTemplateViaSecretRequest" - }, - { - "$ref": "#/definitions/LoadPeerRelationshipTemplateViaReferenceRequest" - } - ] - }, - "LoadPeerRelationshipTemplateViaSecretRequest": { - "type": "object", - "properties": { - "id": { - "$ref": "#/definitions/RelationshipTemplateIdString" - }, - "secretKey": { - "type": "string", - "minLength": 10 - } - }, - "required": [ - "id", - "secretKey" - ], - "additionalProperties": false - }, - "RelationshipTemplateIdString": { - "type": "string", - "pattern": "RLT[A-Za-z0-9]{17}" - }, - "LoadPeerRelationshipTemplateViaReferenceRequest": { "type": "object", "properties": { "reference": { @@ -22962,81 +22747,11 @@ export const GetTokensRequest: any = { } } -export const LoadPeerTokenViaReferenceRequest: any = { - "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/definitions/LoadPeerTokenViaReferenceRequest", - "definitions": { - "LoadPeerTokenViaReferenceRequest": { - "type": "object", - "properties": { - "reference": { - "$ref": "#/definitions/TokenReferenceString" - }, - "ephemeral": { - "type": "boolean" - } - }, - "required": [ - "reference", - "ephemeral" - ], - "additionalProperties": false, - "errorMessage": "token reference invalid" - }, - "TokenReferenceString": { - "type": "string", - "pattern": "VE9L.{84}" - } - } -} - -export const LoadPeerTokenViaSecretRequest: any = { - "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/definitions/LoadPeerTokenViaSecretRequest", - "definitions": { - "LoadPeerTokenViaSecretRequest": { - "type": "object", - "properties": { - "id": { - "$ref": "#/definitions/TokenIdString" - }, - "secretKey": { - "type": "string", - "minLength": 10 - }, - "ephemeral": { - "type": "boolean" - } - }, - "required": [ - "id", - "secretKey", - "ephemeral" - ], - "additionalProperties": false - }, - "TokenIdString": { - "type": "string", - "pattern": "TOK[A-Za-z0-9]{17}" - } - } -} - export const LoadPeerTokenRequest: any = { "$schema": "http://json-schema.org/draft-07/schema#", "$ref": "#/definitions/LoadPeerTokenRequest", "definitions": { "LoadPeerTokenRequest": { - "anyOf": [ - { - "$ref": "#/definitions/LoadPeerTokenViaReferenceRequest" - }, - { - "$ref": "#/definitions/LoadPeerTokenViaSecretRequest" - } - ] - }, - "LoadPeerTokenViaReferenceRequest": { "type": "object", "properties": { "reference": { @@ -23056,31 +22771,6 @@ export const LoadPeerTokenRequest: any = { "TokenReferenceString": { "type": "string", "pattern": "VE9L.{84}" - }, - "LoadPeerTokenViaSecretRequest": { - "type": "object", - "properties": { - "id": { - "$ref": "#/definitions/TokenIdString" - }, - "secretKey": { - "type": "string", - "minLength": 10 - }, - "ephemeral": { - "type": "boolean" - } - }, - "required": [ - "id", - "secretKey", - "ephemeral" - ], - "additionalProperties": false - }, - "TokenIdString": { - "type": "string", - "pattern": "TOK[A-Za-z0-9]{17}" } } } \ No newline at end of file diff --git a/packages/runtime/src/useCases/transport/files/FileMapper.ts b/packages/runtime/src/useCases/transport/files/FileMapper.ts index 3d642775d..463b6778d 100644 --- a/packages/runtime/src/useCases/transport/files/FileMapper.ts +++ b/packages/runtime/src/useCases/transport/files/FileMapper.ts @@ -32,7 +32,6 @@ export class FileMapper { mimetype: file.cache.mimetype, isOwn: file.isOwn, title: file.cache.title ?? "", - secretKey: file.secretKey.toBase64(false), description: file.cache.description, truncatedReference: file.truncate() }; diff --git a/packages/runtime/src/useCases/transport/files/GetOrLoadFile.ts b/packages/runtime/src/useCases/transport/files/GetOrLoadFile.ts index a07f0f4ea..175f197be 100644 --- a/packages/runtime/src/useCases/transport/files/GetOrLoadFile.ts +++ b/packages/runtime/src/useCases/transport/files/GetOrLoadFile.ts @@ -4,72 +4,19 @@ import { CryptoSecretKey } from "@nmshd/crypto"; import { AccountController, FileController, Token, TokenContentFile, TokenController } from "@nmshd/transport"; import { Inject } from "typescript-ioc"; import { FileDTO } from "../../../types"; -import { - Base64ForIdPrefix, - FileIdString, - FileReferenceString, - JsonSchema, - RuntimeErrors, - SchemaRepository, - SchemaValidator, - TokenReferenceString, - UseCase, - ValidationFailure, - ValidationResult -} from "../../common"; +import { Base64ForIdPrefix, FileReferenceString, RuntimeErrors, SchemaRepository, SchemaValidator, TokenReferenceString, UseCase } from "../../common"; import { FileMapper } from "./FileMapper"; -export interface GetOrLoadFileViaSecretRequest { - id: FileIdString; - /** - * @minLength 10 - */ - secretKey: string; -} - /** * @errorMessage token / file reference invalid */ -export interface GetOrLoadFileViaReferenceRequest { +export interface GetOrLoadFileRequest { reference: TokenReferenceString | FileReferenceString; } -export type GetOrLoadFileRequest = GetOrLoadFileViaSecretRequest | GetOrLoadFileViaReferenceRequest; - -function isViaSecret(request: GetOrLoadFileRequest): request is GetOrLoadFileViaSecretRequest { - return "id" in request && "secretKey" in request; -} - -function isViaReference(request: GetOrLoadFileRequest): request is GetOrLoadFileViaSecretRequest { - return "reference" in request; -} - class Validator extends SchemaValidator { - private readonly loadViaSecretSchema: JsonSchema; - private readonly loadViaReferenceSchema: JsonSchema; - public constructor(@Inject schemaRepository: SchemaRepository) { super(schemaRepository.getSchema("GetOrLoadFileRequest")); - this.loadViaSecretSchema = schemaRepository.getSchema("GetOrLoadFileViaSecretRequest"); - this.loadViaReferenceSchema = schemaRepository.getSchema("GetOrLoadFileViaReferenceRequest"); - } - - public override validate(input: GetOrLoadFileRequest): ValidationResult { - if (this.schema.validate(input).isValid) return new ValidationResult(); - - // any-of in combination with missing properties is a bit weird - // when { reference: null | undefined } is passed, it ignores reference - // and treats it like a GetOrLoadFileViaSecret. - // That's why we validate with the specific schema afterwards - if (isViaReference(input)) { - return this.convertValidationResult(this.loadViaReferenceSchema.validate(input)); - } else if (isViaSecret(input)) { - return this.convertValidationResult(this.loadViaSecretSchema.validate(input)); - } - - const result = new ValidationResult(); - result.addFailure(new ValidationFailure(RuntimeErrors.general.invalidPayload())); - return result; } } @@ -84,20 +31,11 @@ export class GetOrLoadFileUseCase extends UseCase } protected async executeInternal(request: GetOrLoadFileRequest): Promise> { - let createdFileResult: Result; - - if (isViaSecret(request)) { - const key = CryptoSecretKey.fromBase64(request.secretKey); - createdFileResult = await this.loadFile(CoreId.from(request.id), key); - } else if (isViaReference(request)) { - createdFileResult = await this.loadFileFromReference(request.reference); - } else { - throw new Error("Invalid request format."); - } + const result = await this.loadFileFromReference(request.reference); await this.accountController.syncDatawallet(); - return createdFileResult; + return result; } private async loadFileFromReference(reference: string): Promise> { diff --git a/packages/runtime/src/useCases/transport/relationshipTemplates/LoadPeerRelationshipTemplate.ts b/packages/runtime/src/useCases/transport/relationshipTemplates/LoadPeerRelationshipTemplate.ts index 5abda01e9..b0ab68548 100644 --- a/packages/runtime/src/useCases/transport/relationshipTemplates/LoadPeerRelationshipTemplate.ts +++ b/packages/runtime/src/useCases/transport/relationshipTemplates/LoadPeerRelationshipTemplate.ts @@ -4,73 +4,19 @@ import { CryptoSecretKey } from "@nmshd/crypto"; import { AccountController, RelationshipTemplateController, Token, TokenContentRelationshipTemplate, TokenController } from "@nmshd/transport"; import { Inject } from "typescript-ioc"; import { RelationshipTemplateDTO } from "../../../types"; -import { - Base64ForIdPrefix, - JsonSchema, - RelationshipTemplateIdString, - RelationshipTemplateReferenceString, - RuntimeErrors, - SchemaRepository, - SchemaValidator, - TokenReferenceString, - UseCase, - ValidationFailure, - ValidationResult -} from "../../common"; +import { Base64ForIdPrefix, RelationshipTemplateReferenceString, RuntimeErrors, SchemaRepository, SchemaValidator, TokenReferenceString, UseCase } from "../../common"; import { RelationshipTemplateMapper } from "./RelationshipTemplateMapper"; -export interface LoadPeerRelationshipTemplateViaSecretRequest { - id: RelationshipTemplateIdString; - /** - * @minLength 10 - */ - secretKey: string; -} - /** * @errorMessage token / relationship template reference invalid */ -export interface LoadPeerRelationshipTemplateViaReferenceRequest { +export interface LoadPeerRelationshipTemplateRequest { reference: TokenReferenceString | RelationshipTemplateReferenceString; } -export type LoadPeerRelationshipTemplateRequest = LoadPeerRelationshipTemplateViaSecretRequest | LoadPeerRelationshipTemplateViaReferenceRequest; - -function isLoadPeerRelationshipTemplateViaSecret(request: LoadPeerRelationshipTemplateRequest): request is LoadPeerRelationshipTemplateViaSecretRequest { - return "id" in request && "secretKey" in request; -} - -function isLoadPeerRelationshipTemplateViaReference(request: LoadPeerRelationshipTemplateRequest): request is LoadPeerRelationshipTemplateViaReferenceRequest { - return "reference" in request; -} - class Validator extends SchemaValidator { - private readonly loadViaSecretSchema: JsonSchema; - private readonly loadViaReferenceSchema: JsonSchema; - public constructor(@Inject schemaRepository: SchemaRepository) { super(schemaRepository.getSchema("LoadPeerRelationshipTemplateRequest")); - - this.loadViaSecretSchema = schemaRepository.getSchema("LoadPeerRelationshipTemplateViaSecretRequest"); - this.loadViaReferenceSchema = schemaRepository.getSchema("LoadPeerRelationshipTemplateViaReferenceRequest"); - } - - public override validate(input: LoadPeerRelationshipTemplateRequest): ValidationResult { - if (this.schema.validate(input).isValid) return new ValidationResult(); - - // any-of in combination with missing properties is a bit weird - // when { reference: null | undefined } is passed, it ignores reference - // and treats it like a LoadPeerFileViaSecret. - // That's why we validate with the specific schema afterwards - if (isLoadPeerRelationshipTemplateViaReference(input)) { - return this.convertValidationResult(this.loadViaReferenceSchema.validate(input)); - } else if (isLoadPeerRelationshipTemplateViaSecret(input)) { - return this.convertValidationResult(this.loadViaSecretSchema.validate(input)); - } - - const result = new ValidationResult(); - result.addFailure(new ValidationFailure(RuntimeErrors.general.invalidPayload())); - return result; } } @@ -85,20 +31,11 @@ export class LoadPeerRelationshipTemplateUseCase extends UseCase> { - let createdTemplateResult: Result; - - if (isLoadPeerRelationshipTemplateViaSecret(request)) { - const key = CryptoSecretKey.fromBase64(request.secretKey); - createdTemplateResult = await this.loadTemplate(CoreId.from(request.id), key); - } else if (isLoadPeerRelationshipTemplateViaReference(request)) { - createdTemplateResult = await this.loadRelationshipTemplateFromReference(request.reference); - } else { - throw new Error("Invalid request format."); - } + const result = await this.loadRelationshipTemplateFromReference(request.reference); await this.accountController.syncDatawallet(); - return createdTemplateResult; + return result; } private async loadRelationshipTemplateFromReference(reference: string): Promise> { diff --git a/packages/runtime/src/useCases/transport/relationshipTemplates/RelationshipTemplateMapper.ts b/packages/runtime/src/useCases/transport/relationshipTemplates/RelationshipTemplateMapper.ts index 6d7e2fdfe..207d2af49 100644 --- a/packages/runtime/src/useCases/transport/relationshipTemplates/RelationshipTemplateMapper.ts +++ b/packages/runtime/src/useCases/transport/relationshipTemplates/RelationshipTemplateMapper.ts @@ -19,7 +19,6 @@ export class RelationshipTemplateMapper { content: this.toTemplateContent(template.cache.content), expiresAt: template.cache.expiresAt?.toString(), maxNumberOfAllocations: template.cache.maxNumberOfAllocations, - secretKey: template.secretKey.toBase64(false), truncatedReference: template.truncate() }; } diff --git a/packages/runtime/src/useCases/transport/tokens/LoadPeerToken.ts b/packages/runtime/src/useCases/transport/tokens/LoadPeerToken.ts index a4c79837f..f8c987e3b 100644 --- a/packages/runtime/src/useCases/transport/tokens/LoadPeerToken.ts +++ b/packages/runtime/src/useCases/transport/tokens/LoadPeerToken.ts @@ -1,65 +1,21 @@ import { Result } from "@js-soft/ts-utils"; -import { CoreId } from "@nmshd/core-types"; -import { CryptoSecretKey } from "@nmshd/crypto"; -import { AccountController, Token, TokenController } from "@nmshd/transport"; +import { AccountController, TokenController } from "@nmshd/transport"; import { Inject } from "typescript-ioc"; import { TokenDTO } from "../../../types"; -import { JsonSchema, RuntimeErrors, SchemaRepository, SchemaValidator, TokenIdString, TokenReferenceString, UseCase, ValidationFailure, ValidationResult } from "../../common"; +import { SchemaRepository, SchemaValidator, TokenReferenceString, UseCase } from "../../common"; import { TokenMapper } from "./TokenMapper"; /** * @errorMessage token reference invalid */ -export interface LoadPeerTokenViaReferenceRequest { +export interface LoadPeerTokenRequest { reference: TokenReferenceString; ephemeral: boolean; } -export interface LoadPeerTokenViaSecretRequest { - id: TokenIdString; - /** - * @minLength 10 - */ - secretKey: string; - ephemeral: boolean; -} - -export type LoadPeerTokenRequest = LoadPeerTokenViaReferenceRequest | LoadPeerTokenViaSecretRequest; - -function isLoadPeerTokenViaSecret(request: LoadPeerTokenRequest): request is LoadPeerTokenViaSecretRequest { - return "id" in request && "secretKey" in request; -} - -function isLoadPeerTokenViaReference(request: LoadPeerTokenRequest): request is LoadPeerTokenViaReferenceRequest { - return "reference" in request; -} - class Validator extends SchemaValidator { - private readonly loadViaSecretSchema: JsonSchema; - private readonly loadViaReferenceSchema: JsonSchema; - public constructor(@Inject schemaRepository: SchemaRepository) { super(schemaRepository.getSchema("LoadPeerTokenRequest")); - this.loadViaSecretSchema = schemaRepository.getSchema("LoadPeerTokenViaSecretRequest"); - this.loadViaReferenceSchema = schemaRepository.getSchema("LoadPeerTokenViaReferenceRequest"); - } - - public override validate(input: LoadPeerTokenRequest): ValidationResult { - if (this.schema.validate(input).isValid) return new ValidationResult(); - - // any-of in combination with missing properties is a bit weird - // when { reference: null | undefined } is passed, it ignores reference - // and treats it like a LoadPeerTokenViaSecret. - // That's why we validate with the specific schema afterwards - if (isLoadPeerTokenViaReference(input)) { - return this.convertValidationResult(this.loadViaReferenceSchema.validate(input)); - } else if (isLoadPeerTokenViaSecret(input)) { - return this.convertValidationResult(this.loadViaSecretSchema.validate(input)); - } - - const result = new ValidationResult(); - result.addFailure(new ValidationFailure(RuntimeErrors.general.invalidPayload())); - return result; } } @@ -73,21 +29,12 @@ export class LoadPeerTokenUseCase extends UseCase> { - let createdToken: Token; - - if (isLoadPeerTokenViaSecret(request)) { - const key = CryptoSecretKey.fromBase64(request.secretKey); - createdToken = await this.tokenController.loadPeerToken(CoreId.from(request.id), key, request.ephemeral); - } else if (isLoadPeerTokenViaReference(request)) { - createdToken = await this.tokenController.loadPeerTokenByTruncated(request.reference, request.ephemeral); - } else { - throw new Error("Invalid request format."); - } + const result = await this.tokenController.loadPeerTokenByTruncated(request.reference, request.ephemeral); if (!request.ephemeral) { await this.accountController.syncDatawallet(); } - return Result.ok(TokenMapper.toTokenDTO(createdToken, request.ephemeral)); + return Result.ok(TokenMapper.toTokenDTO(result, request.ephemeral)); } } diff --git a/packages/runtime/src/useCases/transport/tokens/TokenMapper.ts b/packages/runtime/src/useCases/transport/tokens/TokenMapper.ts index 7827d20b7..9441e6fbf 100644 --- a/packages/runtime/src/useCases/transport/tokens/TokenMapper.ts +++ b/packages/runtime/src/useCases/transport/tokens/TokenMapper.ts @@ -16,7 +16,6 @@ export class TokenMapper { content: token.cache.content.toJSON(), createdAt: token.cache.createdAt.toString(), expiresAt: token.cache.expiresAt.toString(), - secretKey: token.secretKey.toBase64(false), truncatedReference: reference.truncate(), isEphemeral: ephemeral }; diff --git a/packages/runtime/test/anonymous/tokens.test.ts b/packages/runtime/test/anonymous/tokens.test.ts index 4f6f5ddad..dcbdb0c62 100644 --- a/packages/runtime/test/anonymous/tokens.test.ts +++ b/packages/runtime/test/anonymous/tokens.test.ts @@ -25,7 +25,7 @@ describe("Anonymous tokens", () => { }); test("should get the token anonymous by truncated reference", async () => { - const result = await noLoginRuntime.anonymousServices.tokens.loadPeerTokenByTruncatedReference({ + const result = await noLoginRuntime.anonymousServices.tokens.loadPeerToken({ reference: uploadedToken.truncatedReference }); expect(result).toBeSuccessful(); @@ -33,15 +33,4 @@ describe("Anonymous tokens", () => { const token = result.value; expect(token.content).toStrictEqual(uploadedToken.content); }); - - test("should get the token anonymous by id and key", async () => { - const result = await noLoginRuntime.anonymousServices.tokens.loadPeerTokenByIdAndKey({ - id: uploadedToken.id, - secretKey: uploadedToken.secretKey - }); - expect(result).toBeSuccessful(); - - const token = result.value; - expect(token.content).toStrictEqual(uploadedToken.content); - }); }); diff --git a/packages/runtime/test/transport/files.test.ts b/packages/runtime/test/transport/files.test.ts index bf7e40f4a..3cfb69699 100644 --- a/packages/runtime/test/transport/files.test.ts +++ b/packages/runtime/test/transport/files.test.ts @@ -315,11 +315,11 @@ describe("Load peer file with token reference", () => { test("passing empty object causes an error", async () => { const response = await transportServices2.files.getOrLoadFile({} as any); - expect(response).toBeAnError("The given combination of properties in the payload is not supported.", "error.runtime.validation.invalidPayload"); + expect(response).toBeAnError("token / file reference invalid", "error.runtime.validation.invalidPropertyValue"); }); }); -describe("Load peer file with file id and secret", () => { +describe("Load peer file with the FileReference", () => { let file: FileDTO; beforeAll(async () => { @@ -333,13 +333,9 @@ describe("Load peer file with file id and secret", () => { expect(response).toBeAnError("File not found. Make sure the ID exists and the record is not expired.", "error.runtime.recordNotFound"); }); - test("peer file can be loaded with file id and secret key", async () => { - expect(file).toBeDefined(); - - const response = await transportServices2.files.getOrLoadFile({ id: file.id, secretKey: file.secretKey }); - - expect(response).toBeSuccessful(); - expect(response.value).toMatchObject({ ...file, isOwn: false }); + test("load the file using the FileReference", async () => { + const fileResult = await transportServices2.files.getOrLoadFile({ reference: file.truncatedReference }); + expect(fileResult).toBeSuccessful(); }); test("after peer file is loaded the file can be accessed under /Files/{id}", async () => { @@ -357,53 +353,4 @@ describe("Load peer file with file id and secret", () => { expect(response).toBeSuccessful(); expect(response.value).toContainEqual({ ...file, isOwn: false }); }); - - test("cannot pass an unkown file id", async () => { - expect(file).toBeDefined(); - - const response = await transportServices2.files.getOrLoadFile({ id: UNKNOWN_FILE_ID, secretKey: file.secretKey }); - - expect(response).toBeAnError("File not found. Make sure the ID exists and the record is not expired.", "error.runtime.recordNotFound"); - }); - - test("cannot pass an unkown token id as file id", async () => { - expect(file).toBeDefined(); - - const response = await transportServices2.files.getOrLoadFile({ id: UNKNOWN_TOKEN_ID, secretKey: file.secretKey }); - - expect(response).toBeAnError("id must match pattern FIL.*", "error.runtime.validation.invalidPropertyValue"); - }); - - test.each([ - [null, "secretKey must be string"], - [undefined, "must have required property 'secretKey'"], - ["", "secretKey must NOT have fewer than 10 characters"] - ])("cannot pass %p as secret key", async (secretKey, expectedMessage) => { - const response = await transportServices2.files.getOrLoadFile({ id: file.id, secretKey: secretKey! }); - - expect(response).toBeAnError(expectedMessage, "error.runtime.validation.invalidPropertyValue"); - }); - - test.each([ - [null, "id must be string"], - [undefined, "must have required property 'id'"], - ["", "id must match pattern FIL.*"] - ])("cannot pass %p as file id", async (fileId, expectedMessage) => { - const response = await transportServices2.files.getOrLoadFile({ id: fileId!, secretKey: file.secretKey }); - - expect(response).toBeAnError(expectedMessage, "error.runtime.validation.invalidPropertyValue"); - }); -}); - -describe("Load peer file with the FileReference", () => { - let file: FileDTO; - - beforeAll(async () => { - file = await uploadFile(transportServices1); - }); - - test("load the file using the FileReference", async () => { - const fileResult = await transportServices2.files.getOrLoadFile({ reference: file.truncatedReference }); - expect(fileResult).toBeSuccessful(); - }); }); diff --git a/packages/transport/package.json b/packages/transport/package.json index 41070b9af..e9d953ba9 100644 --- a/packages/transport/package.json +++ b/packages/transport/package.json @@ -90,7 +90,7 @@ "@js-soft/node-logger": "1.2.0", "@js-soft/ts-serval": "2.0.11", "@types/json-stringify-safe": "^5.0.3", - "@types/lodash": "^4.17.7", + "@types/lodash": "^4.17.9", "@types/luxon": "^3.4.2", "@types/qs": "^6.9.16", "@types/uuid": "^10.0.0", diff --git a/packages/transport/src/modules/messages/MessageController.ts b/packages/transport/src/modules/messages/MessageController.ts index 13d14511f..bfa1596ad 100644 --- a/packages/transport/src/modules/messages/MessageController.ts +++ b/packages/transport/src/modules/messages/MessageController.ts @@ -507,10 +507,10 @@ export class MessageController extends TransportController { ); } } else { - relationship = await this.relationships.getActiveRelationshipToIdentity(envelope.createdBy); + relationship = await this.relationships.getRelationshipToIdentity(envelope.createdBy); if (!relationship) { - throw TransportCoreErrors.messages.missingOrInactiveRelationship(envelope.createdBy.toString()); + throw TransportCoreErrors.general.recordNotFound(Relationship, envelope.createdBy.toString()); } const [peerMessage, peerKey] = await this.decryptPeerEnvelope(envelope, relationship); diff --git a/packages/transport/test/modules/messages/MessageController.test.ts b/packages/transport/test/modules/messages/MessageController.test.ts index 0ed4e2112..63a484f46 100644 --- a/packages/transport/test/modules/messages/MessageController.test.ts +++ b/packages/transport/test/modules/messages/MessageController.test.ts @@ -219,12 +219,20 @@ describe("MessageController", function () { }); describe("Relationship Termination", function () { + let messageId: CoreId; + beforeAll(async function () { + messageId = (await TestUtil.sendMessage(sender, recipient)).id; await TestUtil.terminateRelationship(sender, recipient); }); test("should not send a message on a terminated relationship", async function () { await expect(TestUtil.sendMessage(sender, recipient)).rejects.toThrow("error.transport.messages.missingOrInactiveRelationship"); }); + + test("should still decrypt the message", async function () { + await expect(sender.messages.fetchCaches([messageId])).resolves.not.toThrow(); + await expect(recipient.messages.fetchCaches([messageId])).resolves.not.toThrow(); + }); }); });