taler-typescript-core

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

commit c66d8c7961b6686e8c71dfeca0137cabc4bad711
parent f15d87ade77297429d753edbff679fb8e1fa95e8
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Wed, 21 Oct 2026 15:53:56 +0200

mailbox/taldir: Fix alias unlinking with recent API changes, update contacts to include version and self fields for alias management

Diffstat:
Mpackages/taler-util/src/types-taler-wallet.ts | 12++++++++++++
Mpackages/taler-wallet-core/src/contacts.ts | 2++
Mpackages/taler-wallet-core/src/db/indexeddb/schema.ts | 10++++++++++
Mpackages/taler-wallet-core/src/db/indexeddb/transaction.ts | 4++++
Mpackages/taler-wallet-core/src/db/sqlite/schema.ts | 12+++++++++++-
Mpackages/taler-wallet-core/src/db/sqlite/transaction.ts | 12+++++++++---
Mpackages/taler-wallet-core/src/taldir.ts | 10++++++++--
7 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/packages/taler-util/src/types-taler-wallet.ts b/packages/taler-util/src/types-taler-wallet.ts @@ -1813,6 +1813,8 @@ export const codecForContactEntry = (): Codec<ContactEntry> => .property("aliasType", codecForString()) .property("mailboxBaseUrl", codecForString()) .property("mailboxAddress", codecForString()) + .property("self", codecOptional(codecForBoolean())) + .property("version", codecOptional(codecForNumber())) .property("source", codecForString()) .property("petname", codecForString()) .build("ContactListItem"); @@ -2249,6 +2251,16 @@ export interface ContactEntry { mailboxAddress: HashCodeString; /** + * Is this a self-contact? + */ + self?: boolean; + + /** + * Version of the contact. + */ + version?: number; + + /** * The source of this contact * may be a URI */ diff --git a/packages/taler-wallet-core/src/contacts.ts b/packages/taler-wallet-core/src/contacts.ts @@ -45,6 +45,8 @@ async function makeContactListItem( mailboxAddress: r.mailboxAddress, source: r.source, petname: r.petname, + self: r.self ?? false, + version: r.version ?? 0, }; return listItem; } diff --git a/packages/taler-wallet-core/src/db/indexeddb/schema.ts b/packages/taler-wallet-core/src/db/indexeddb/schema.ts @@ -505,6 +505,16 @@ export interface ContactRecord { */ petname: string; + /** + * Is this a self-contact? + */ + self?: boolean; + + /** + * Version of the contact. + */ + version?: number; + // Reserved legacy fields, migrated by the IndexedDB fixup: // * mailboxUri: string } diff --git a/packages/taler-wallet-core/src/db/indexeddb/transaction.ts b/packages/taler-wallet-core/src/db/indexeddb/transaction.ts @@ -276,6 +276,8 @@ export class IdbWalletTransaction implements WalletDbTransaction { mailboxAddress: contact.mailboxAddress, source: contact.source, petname: contact.petname, + self: contact.self, + version: contact.version, }); } @@ -294,6 +296,8 @@ export class IdbWalletTransaction implements WalletDbTransaction { mailboxAddress: r.mailboxAddress, source: r.source, petname: r.petname, + self: r.self, + version: r.version, })); } diff --git a/packages/taler-wallet-core/src/db/sqlite/schema.ts b/packages/taler-wallet-core/src/db/sqlite/schema.ts @@ -85,7 +85,7 @@ * * Bump this when adding a migration to {@link schemaMigrations}. */ -export const SQLITE_SCHEMA_VERSION = 24; +export const SQLITE_SCHEMA_VERSION = 25; /** * Tables of the IndexedDB emulation, children before parents. @@ -356,6 +356,8 @@ CREATE TABLE IF NOT EXISTS contacts ( mailbox_address TEXT NOT NULL, source TEXT NOT NULL, petname TEXT NOT NULL, + self INTEGER DEFAULT 0, + version INTEGER DEFAULT 0, PRIMARY KEY (alias, alias_type) ); @@ -1519,6 +1521,14 @@ export const schemaMigrations: SchemaMigration[] = [ "ALTER TABLE refund_items ADD COLUMN fail_reason TEXT", ], }, + { + version: 25, + name: "contact-self-and-version", + statements: [ + "ALTER TABLE contacts ADD COLUMN self INTEGER DEFAULT 0", + "ALTER TABLE contacts ADD COLUMN version INTEGER DEFAULT 0", + ], + }, ]; /** Native tables that contain wallet records (not schema bookkeeping). */ diff --git a/packages/taler-wallet-core/src/db/sqlite/transaction.ts b/packages/taler-wallet-core/src/db/sqlite/transaction.ts @@ -4702,13 +4702,15 @@ export class SqliteWalletTransaction implements WalletDbTransaction { async addContact(contact: ContactEntry): Promise<void> { await this.run( `INSERT INTO contacts ( - alias, alias_type, mailbox_base_uri, mailbox_address, source, petname - ) VALUES ($alias, $type, $uri, $addr, $src, $pet) + alias, alias_type, mailbox_base_uri, mailbox_address, source, petname, self, version + ) VALUES ($alias, $type, $uri, $addr, $src, $pet, $self, $version) ON CONFLICT(alias, alias_type) DO UPDATE SET mailbox_base_uri = excluded.mailbox_base_uri, mailbox_address = excluded.mailbox_address, source = excluded.source, - petname = excluded.petname`, + petname = excluded.petname, + self = excluded.self, + version = excluded.version`, { alias: contact.alias, type: contact.aliasType, @@ -4716,6 +4718,8 @@ export class SqliteWalletTransaction implements WalletDbTransaction { addr: contact.mailboxAddress, src: contact.source, pet: contact.petname, + self: boolToDb(contact.self ?? false), + version: contact.version ?? 0, }, ); } @@ -4736,6 +4740,8 @@ export class SqliteWalletTransaction implements WalletDbTransaction { mailboxAddress: str(row.mailbox_address), source: str(row.source), petname: str(row.petname), + self: dbToOptBool(row.self), + version: typeof row.version === "number" ? row.version : 0, })); } diff --git a/packages/taler-wallet-core/src/taldir.ts b/packages/taler-wallet-core/src/taldir.ts @@ -190,7 +190,10 @@ async function internalRegisterAlias( registerRequest.taldirBaseUrl, wex.http, ); - const targetUri = registerRequest.mailboxBaseUrl + "/" + registerRequest.mailboxAddress; + const targetUri = + registerRequest.mailboxBaseUrl && registerRequest.mailboxAddress + ? `${registerRequest.mailboxBaseUrl.replace(/\/+$/, "")}/${registerRequest.mailboxAddress}` + : ""; const res = await taldirClient.postRegistrationRequest({ alias: registerRequest.alias, aliasType: registerRequest.aliasType, @@ -238,7 +241,10 @@ async function internalCompleteAliasRegistration( completionRequest.taldirBaseUrl, wex.http, ); - const targetUri = completionRequest.mailboxBaseUrl + "/" + completionRequest.mailboxAddress; + const targetUri = + completionRequest.mailboxBaseUrl && completionRequest.mailboxAddress + ? `${completionRequest.mailboxBaseUrl.replace(/\/+$/, "")}/${completionRequest.mailboxAddress}` + : ""; const encoder = new TextEncoder(); const bytes1 = encoder.encode(completionRequest.challenge); const bytes2 = encoder.encode(targetUri);