fix a single conditional such that reference to a previous claim isn't lost

This commit is contained in:
2026-10-24 15:54:57 -06:00
parent 9442ea716d
commit 2e268dbb84
3 changed files with 84 additions and 20 deletions
+33
View File
@@ -0,0 +1,33 @@
/**
* @fileoverview How a confirmation names the claim it confirms
*
* This module depends only on ramda so that it stays loadable and testable
* without a database, a network client, or a build-time environment.
*
* @module confirmationTarget
*/
import * as R from "ramda";
// similar logic is found in endorser-mobile
// The lastClaimId is added even when there's an identifier, because one handle
// can hold different claims (eg. every Person claim about a DID shares that DID
// as its handle) and the server would otherwise take the latest one.
export function addLastClaimOrHandleAsIdIfMissing(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
obj: any,
lastClaimId?: string,
handleId?: string,
) {
if (!obj.lastClaimId && lastClaimId) {
const result = R.clone(obj);
result.lastClaimId = lastClaimId;
return result;
} else if (!obj.identifier && handleId) {
const result = R.clone(obj);
result.identifier = handleId;
return result;
} else {
return obj;
}
}
+4 -20
View File
@@ -22,6 +22,8 @@ import { sha256 } from "ethereum-cryptography/sha256";
import { LRUCache } from "lru-cache";
import * as R from "ramda";
import { addLastClaimOrHandleAsIdIfMissing } from "./confirmationTarget";
import { DEFAULT_IMAGE_API_SERVER, NotificationIface } from "../constants/app";
import { NOTIFICATION_TIMEOUTS } from "../utils/notificationUtils";
import { createNotifyHelpers } from "../utils/notify";
@@ -112,6 +114,8 @@ export {
addEndorserPrefix,
stripEndorserPrefix,
} from "./endorserHandleIds";
// Same reason as above.
export { addLastClaimOrHandleAsIdIfMissing } from "./confirmationTarget";
export const BLANK_GENERIC_SERVER_RECORD: GenericCredWrapper<GenericVerifiableCredential> =
{
@@ -233,26 +237,6 @@ export function removeSchemaContext(obj: any) {
: obj;
}
// similar logic is found in endorser-mobile
export function addLastClaimOrHandleAsIdIfMissing(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
obj: any,
lastClaimId?: string,
handleId?: string,
) {
if (!obj.identifier && lastClaimId) {
const result = R.clone(obj);
result.lastClaimId = lastClaimId;
return result;
} else if (!obj.identifier && handleId) {
const result = R.clone(obj);
result.identifier = handleId;
return result;
} else {
return obj;
}
}
// return clone of object without any nested *VisibleToDids keys
// similar code is also contained in endorser-mobile
// eslint-disable-next-line @typescript-eslint/no-explicit-any
+47
View File
@@ -0,0 +1,47 @@
import { addLastClaimOrHandleAsIdIfMissing } from "@/libs/confirmationTarget";
/**
* A confirmation names the claim it confirms. Every Person claim about a DID
* has that DID as its identifier, so the identifier alone points the server at
* whichever of them is latest, not at the one on screen.
*/
const DID = "did:ethr:0xce097412b1Cc8E0DBe294b3d8243e2b3Cf8E80ba";
const CLAIM_ID = "01M0QQ897FZ15R2KMZFSZ66W7V";
const HANDLE_ID = "https://endorser.ch/entity/01M0QQ897FZ15R2KMZFSZ66W7V";
describe("addLastClaimOrHandleAsIdIfMissing", () => {
it("names the exact claim even when it has an identifier", () => {
const claim = { "@type": "Person", identifier: DID };
expect(addLastClaimOrHandleAsIdIfMissing(claim, CLAIM_ID, DID)).toEqual({
"@type": "Person",
identifier: DID,
lastClaimId: CLAIM_ID,
});
});
it("does not change the claim it was given", () => {
const claim = { "@type": "Person", identifier: DID };
addLastClaimOrHandleAsIdIfMissing(claim, CLAIM_ID, DID);
expect(claim).toEqual({ "@type": "Person", identifier: DID });
});
it("keeps a lastClaimId the claim already carries", () => {
const claim = { "@type": "Person", lastClaimId: "01EARLIER" };
expect(addLastClaimOrHandleAsIdIfMissing(claim, CLAIM_ID)).toBe(claim);
});
it("falls back to the handle as identifier when there is no claim ID", () => {
const claim = { "@type": "GiveAction" };
expect(
addLastClaimOrHandleAsIdIfMissing(claim, undefined, HANDLE_ID),
).toEqual({ "@type": "GiveAction", identifier: HANDLE_ID });
});
it("keeps an identifier the claim already carries over the handle", () => {
const claim = { "@type": "Person", identifier: DID };
expect(addLastClaimOrHandleAsIdIfMissing(claim, undefined, HANDLE_ID)).toBe(
claim,
);
});
});