Skip to content
Open
12 changes: 6 additions & 6 deletions .dev/compose.backbone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: local-test-backbone

services:
consumer-api:
image: ghcr.io/nmshd/backbone-consumer-api:7.1.2@sha256:9948ad32a5c0d280df0049934f14d5f2e572b78167a2c8f62054cd0db1920ac7
image: ghcr.io/nmshd/backbone-consumer-api:7.1.3@sha256:25c09fd48f6380ca6b953dccacdac06a16c28ebfd4945c81a0b7ee5bbef829b5
container_name: consumer-api
hostname: consumer-api
environment:
Expand All @@ -25,7 +25,7 @@ services:
target: app/appsettings.override.json

event-handler-service:
image: ghcr.io/nmshd/backbone-event-handler:7.1.2@sha256:48b3dccc918d2bd1cdbf85058d9b2638a5175b6afb5ada60a744657a35fa2531
image: ghcr.io/nmshd/backbone-event-handler:7.1.3@sha256:c9f9d57f484b8f678d1a3a84895b59d4f952f00e7ab02a55d15e59a7eae2fb11
container_name: event-handler-service
depends_on:
database:
Expand All @@ -39,7 +39,7 @@ services:
target: app/appsettings.override.json

sse-server:
image: ghcr.io/nmshd/backbone-sse-server:7.1.2@sha256:e702c6af79e8f04d5cfd86d38fb0b103b753c20f64b13d5b5a9b9b4e09e8a21a
image: ghcr.io/nmshd/backbone-sse-server:7.1.3@sha256:5840d7cfa54187fa59154b8099c6586833b90965b5f92f26a38bdcefbc8fb4ec
container_name: sse-server
hostname: sse-server
ports:
Expand All @@ -52,7 +52,7 @@ services:
target: app/appsettings.override.json

admin-ui:
image: ghcr.io/nmshd/backbone-admin-ui:7.1.2@sha256:3d59df401a471e8f2606cfd342f598136f12794f4e75a2f5eeb1b3bce47a959a
image: ghcr.io/nmshd/backbone-admin-ui:7.1.3@sha256:637d671ed7a5aafd71807a4febabb0da8f8f05394da59f59a53b6a013b8a232d
container_name: admin-ui
hostname: admin-ui
ports:
Expand All @@ -72,7 +72,7 @@ services:

database-migrator:
container_name: database-migrator
image: ghcr.io/nmshd/backbone-database-migrator:7.1.2@sha256:7f5781feec57c4e60032cf6d3ba47fc9ab9da5e13f530d8d326d58685f174609
image: ghcr.io/nmshd/backbone-database-migrator:7.1.3@sha256:120b724eeddb58bb5f8c4aa2d9107e322bb6eea1707498daf932e6328464af58
environment:
Infrastructure__SqlDatabase__Provider: Postgres
Infrastructure__SqlDatabase__ConnectionString: "Server=postgres;Database=enmeshed;User Id=postgres;Password=Passw0rd;Port=5432"
Expand Down Expand Up @@ -115,7 +115,7 @@ services:

seed-client:
container_name: seed-client
image: ghcr.io/nmshd/backbone-admin-cli:7.1.2@sha256:df2e51e181f98f666e5054d86005e015c3f126d8673a389ecc0fe508e22046ce
image: ghcr.io/nmshd/backbone-admin-cli:7.1.3@sha256:619aa192e3ce925c22342fa7bb3dd82437ad5fe6281c7f9fb84dad33d5dd3646
depends_on:
consumer-api:
condition: service_healthy
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/src/dataViews/DataViewExpander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ export class DataViewExpander {
}

let proposedValueOverruled = false;
if (responseItemDVO && responseItemDVO.result === ResponseItemResult.Accepted) {
if (responseItemDVO?.result === ResponseItemResult.Accepted) {
if (responseItemDVO.type === "AttributeSuccessionAcceptResponseItemDVO") {
const attributeSuccessionResponseItem = responseItemDVO as AttributeSuccessionAcceptResponseItemDVO;
proposedValueOverruled = !_.isEqual(attributeSuccessionResponseItem.successor.content.value, proposeAttributeRequestItem.attribute.value);
Expand Down
1 change: 1 addition & 0 deletions packages/transport/src/modules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export * from "./tokens/backbone/BackboneGetTokens";
export * from "./tokens/backbone/BackbonePostTokens";
export * from "./tokens/backbone/TokenClient";
export * from "./tokens/local/EmptyToken";
export * from "./tokens/local/SendEmptyTokenParameters";
export * from "./tokens/local/SendTokenParameters";
export * from "./tokens/local/Token";
export * from "./tokens/TokenController";
Expand Down
25 changes: 24 additions & 1 deletion packages/transport/src/modules/tokens/TokenController.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ISerializable, Serializable } from "@js-soft/ts-serval";
import { log } from "@js-soft/ts-utils";
import { CoreAddress, CoreDate, CoreId } from "@nmshd/core-types";
import { CoreAddress, CoreDate, CoreId, Random, RandomCharacterRange } from "@nmshd/core-types";
import { CoreBuffer, CryptoCipher, CryptoSecretKey } from "@nmshd/crypto";
import { CoreCrypto, TransportCoreErrors } from "../../core";
import { DbCollectionName } from "../../core/DbCollectionName";
Expand All @@ -10,6 +10,8 @@ import { AccountController } from "../accounts/AccountController";
import { SynchronizedCollection } from "../sync/SynchronizedCollection";
import { BackboneGetTokensResponse } from "./backbone/BackboneGetTokens";
import { TokenClient } from "./backbone/TokenClient";
import { EmptyToken } from "./local/EmptyToken";
import { ISendEmptyTokenParameters, SendEmptyTokenParameters } from "./local/SendEmptyTokenParameters";
import { ISendTokenParameters, SendTokenParameters } from "./local/SendTokenParameters";
import { Token } from "./local/Token";
import { IUpdateTokenContentParameters, UpdateTokenContentParameters } from "./local/UpdateTokenContentParameters";
Expand Down Expand Up @@ -87,6 +89,27 @@ export class TokenController extends TransportController {
return token;
}

public async sendEmptyToken(parameters: ISendEmptyTokenParameters): Promise<EmptyToken> {
const input = SendEmptyTokenParameters.from(parameters);
const secretKey = await CoreCrypto.generateSecretKey();

const password = await Random.string(16, RandomCharacterRange.Alphanumeric + RandomCharacterRange.SpecialCharacters);
const salt = await CoreCrypto.random(16);
const hashedPassword = (await CoreCrypto.deriveHashOutOfPassword(password, salt)).toBase64();
const passwordProtection = PasswordProtection.from({ password, passwordType: "pw", salt });

const response = (await this.client.createEmptyToken({ password: hashedPassword, expiresAt: input.expiresAt.toISOString() })).value;

const token = EmptyToken.from({
id: CoreId.from(response.id),
secretKey: secretKey,
expiresAt: input.expiresAt,
passwordProtection
});

return token;
}

@log()
public async setTokenMetadata(idOrToken: CoreId | Token, metadata: ISerializable): Promise<Token> {
const id = idOrToken instanceof CoreId ? idOrToken.toString() : idOrToken.id.toString();
Expand Down
4 changes: 4 additions & 0 deletions packages/transport/src/modules/tokens/backbone/TokenClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export class TokenClient extends RESTClientAuthenticate {
return await this.post<BackbonePostTokensResponse>("/api/v2/Tokens", token);
}

public async createEmptyToken(request: Omit<BackbonePostTokensRequest, "content">): Promise<ClientResult<BackbonePostTokensResponse>> {
return await this.post<BackbonePostTokensResponse>("/api/v2/Tokens", request);
}

public async updateTokenContent(request: BackboneUpdateTokenContentRequest): Promise<ClientResult<BackboneUpdateTokenContentResponse>> {
return await this.post<BackboneUpdateTokenContentResponse>(`/api/v2/Tokens/${request.id}/UpdateContent`, request);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ISerializable, Serializable, serialize, type, validate } from "@js-soft/ts-serval";
import { CoreDate, ICoreDate } from "@nmshd/core-types";

export interface ISendEmptyTokenParameters extends ISerializable {
expiresAt: ICoreDate;
}

@type("SendEmptyTokenParameters")
export class SendEmptyTokenParameters extends Serializable implements ISendEmptyTokenParameters {
@validate()
@serialize()
public expiresAt: CoreDate;

public static from(value: ISendEmptyTokenParameters): SendEmptyTokenParameters {
return this.fromAny(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export interface IUpdateTokenContentParameters extends ISerializable {
passwordProtection: ISharedPasswordProtection;
}

@type("SendTokenParameters")
@type("UpdateTokenContentParameters")
export class UpdateTokenContentParameters extends Serializable implements IUpdateTokenContentParameters {
@validate()
@serialize()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ describe("TokenController", function () {
expect((receivedToken.content as any).content).toBe((sentToken.content as any).content);
});

test("should send an empty token", async function () {
const expiresAt = CoreDate.utc().add({ hours: 1 });
const sentToken = await sender.tokens.sendEmptyToken({
expiresAt
});

expect(sentToken).toBeDefined();
});

test("should get the stored token", async function () {
const sentToken = await sender.tokens.getToken(tempId1);
const receivedToken = await recipient.tokens.getToken(tempId1);
Expand Down