taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit d65f5bc92e961ecfb22d2f4e7e8dc9a6dcbc8fc3
parent 907fb2ebf4c9b68ddc1b9ce9d5f8055d24b3552d
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Tue, 27 Oct 2026 11:13:08 +0100

mailbox/contacts: fix broken migration

Diffstat:
Mpackages/taler-util/src/http-client/taldir.ts | 6+++---
Mpackages/taler-util/src/types-taler-directory.ts | 3+++
Mpackages/taler-util/src/types-taler-wallet.ts | 12+++++++++++-
Mpackages/taler-wallet-core/src/contacts.ts | 1+
Mpackages/taler-wallet-core/src/db/sqlite/schema.ts | 6+++++-
Mpackages/taler-wallet-core/src/taldir.ts | 12+++++++-----
Mpackages/taler-wallet-core/src/wallet-api-types.ts | 3++-
7 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/packages/taler-util/src/http-client/taldir.ts b/packages/taler-util/src/http-client/taldir.ts @@ -136,7 +136,7 @@ export class TalerDirectoryInstanceHttpClient { hAlias: string; solution: string; }): Promise< - | OperationOk<HttpStatusCode.NoContent> + | OperationOk<TaldirAlreadyPaidResponse> | OperationFail<HttpStatusCode.Forbidden> | OperationFail<HttpStatusCode.NotFound> | OperationFail<HttpStatusCode.TooManyRequests> @@ -153,8 +153,8 @@ export class TalerDirectoryInstanceHttpClient { }); switch (resp.status) { - case HttpStatusCode.NoContent: { - return opFixedSuccess(resp, resp.status); + case HttpStatusCode.Ok: { + return opSuccessFromHttp(resp, codecForTaldirAlreadyPaidResponse()); } case HttpStatusCode.NotFound: case HttpStatusCode.TooManyRequests: diff --git a/packages/taler-util/src/types-taler-directory.ts b/packages/taler-util/src/types-taler-directory.ts @@ -68,6 +68,9 @@ export interface TalerDirectoryConfigResponse { export interface TaldirMailboxDetailResponse { // Target URI to associate with this alias. target_uri: string; + + // The remaining duration for which this registration is still paid for + valid_for?: RelativeTime; } export interface TaldirAlreadyPaidResponse { diff --git a/packages/taler-util/src/types-taler-wallet.ts b/packages/taler-util/src/types-taler-wallet.ts @@ -1700,6 +1700,7 @@ export const codecForTaldirLookupRequest = (): Codec<TaldirLookupRequest> => export interface TaldirLookupResponse { targetUri?: string; + validFor?: RelativeTime; } export interface TaldirSupportedAliasesResponse { @@ -1817,6 +1818,7 @@ export const codecForContactEntry = (): Codec<ContactEntry> => .property("isSelf", codecOptional(codecForBoolean())) .property("source", codecForString()) .property("petname", codecForString()) + .property("expiration", codecOptional(codecForAbsoluteTime)) .build("ContactListItem"); export const codecForAddContactRequest = (): Codec<AddContactRequest> => @@ -2265,6 +2267,11 @@ export interface ContactEntry { * The local petname of the contact */ petname: string; + + /** + * The soft expiration of this entry + */ + expiration?: AbsoluteTime; } /** @@ -2279,6 +2286,9 @@ export interface MailboxMessageRecord { // Taler URI in message talerUri: string; + + // Optional subjectHint + subjectHint?: string; } export interface AcceptManualWithdrawalResult { @@ -2543,7 +2553,7 @@ export interface TestPayArgs { export const codecForTestPayArgs = (): Codec<TestPayArgs> => buildCodecForObject<TestPayArgs>() - .property("merchantBaseUrl", codecForCanonBaseUrl()) + .property("merchantBaseUrl", codecForCanonBaseUrl()) .property("merchantAuthToken", codecOptional(codecForString())) .property("amount", codecForAmountString()) .property("summary", codecForString()) diff --git a/packages/taler-wallet-core/src/contacts.ts b/packages/taler-wallet-core/src/contacts.ts @@ -46,6 +46,7 @@ async function makeContactListItem( source: r.source, petname: r.petname, isSelf: r.isSelf ?? false, + expiration: r.expiration, }; return listItem; } diff --git a/packages/taler-wallet-core/src/db/sqlite/schema.ts b/packages/taler-wallet-core/src/db/sqlite/schema.ts @@ -357,6 +357,7 @@ CREATE TABLE IF NOT EXISTS contacts ( source TEXT NOT NULL, petname TEXT NOT NULL, self INTEGER DEFAULT 0, + expiration INTEGER DEFAULT 0, PRIMARY KEY (alias, alias_type) ); @@ -366,6 +367,7 @@ CREATE TABLE IF NOT EXISTS mailbox_messages ( -- The record type carries a protocol Timestamp ({ t_s }); the mapper -- converts, as it does for every other time in this schema. downloaded_at INTEGER NOT NULL, + subject_hint TEXT NOT NULL, PRIMARY KEY (origin_mailbox_base_url, taler_uri) ); @@ -1522,9 +1524,11 @@ export const schemaMigrations: SchemaMigration[] = [ }, { version: 25, - name: "contact-self-and-version", + name: "contact-and-mailbox", statements: [ "ALTER TABLE contacts ADD COLUMN self INTEGER DEFAULT 0", + "ALTER TABLE contacts ADD COLUMN expiration INTEGER DEFAULT 0", + "ALTER TABLE mailbox_messages ADD COLUMN subject_hint TEXT", ], }, ]; diff --git a/packages/taler-wallet-core/src/taldir.ts b/packages/taler-wallet-core/src/taldir.ts @@ -36,6 +36,7 @@ import { TalerError, TalerErrorCode, succeedOrThrow, + TaldirAlreadyPaidResponse, } from "@gnu-taler/taler-util"; import { WalletExecutionContext } from "./wallet.js"; import { @@ -157,12 +158,13 @@ async function internalLookupAlias( ); const hAlias = encodeCrock(sha512(hAliasBuffer)); const res = await runWithProgressRetries(wex, async () => - await taldirClient.lookupAlias({ hAlias: hAlias }), + await taldirClient.lookupAlias({ hAlias: hAlias }), ); switch (res.case) { case "ok": return { targetUri: res.body?.target_uri, + validFor: res.body?.valid_for, }; case HttpStatusCode.NotFound: return { @@ -236,7 +238,7 @@ async function internalRegisterAlias( export async function completeAliasRegistration( wex: WalletExecutionContext, req: TaldirRegistrationCompletionRequest, -): Promise<EmptyObject> { +): Promise<TaldirAlreadyPaidResponse> { return runWithMaybeProgressContext( wex, "completeAliasRegistration", @@ -248,7 +250,7 @@ export async function completeAliasRegistration( async function internalCompleteAliasRegistration( wex: WalletExecutionContext, completionRequest: TaldirRegistrationCompletionRequest, -): Promise<EmptyObject> { +): Promise<TaldirAlreadyPaidResponse> { const taldirClient = new TalerDirectoryInstanceHttpClient( completionRequest.taldirBaseUrl, wex.http, @@ -271,14 +273,14 @@ async function internalCompleteAliasRegistration( ); const hAlias = encodeCrock(sha512(hAliasBuffer)); const res = await runWithProgressRetries(wex, async () => - await taldirClient.postRegistration({ + await taldirClient.postRegistration({ hAlias: hAlias, solution: solution, }), ); switch (res.case) { case "ok": - return {}; + return res.body; case HttpStatusCode.NotFound: case HttpStatusCode.Forbidden: case HttpStatusCode.TooManyRequests: diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts @@ -234,6 +234,7 @@ import { MailboxRefreshRequest, MailboxInitializationRequest, GetMailboxRequest, + TaldirAlreadyPaidResponse, } from "@gnu-taler/taler-util"; import { PaymentBalanceDetails } from "./balance.js"; import { WithdrawTestBalanceResult } from "./testing.js"; @@ -621,7 +622,7 @@ export type RegisterAliasOp = { export type CompleteRegisterAliasOp = { op: WalletApiOperation.CompleteRegisterAlias; request: TaldirRegistrationCompletionRequest; - response: EmptyObject; + response: TaldirAlreadyPaidResponse; }; /**