Skip to content

Commit

Permalink
feat: providerIdentityClaimId is now apart of ClaimLinkIdentity c…
Browse files Browse the repository at this point in the history
…laims stored in the local `SigChain`
  • Loading branch information
amydevs committed May 17, 2024
1 parent efefb46 commit 392615e
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 42 deletions.
7 changes: 6 additions & 1 deletion src/claims/payloads/claimLinkIdentity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import type { Claim, SignedClaim } from '../types';
import type { NodeIdEncoded, ProviderIdentityIdEncoded } from '../../ids/types';
import type {
NodeIdEncoded,
ProviderIdentityClaimId,
ProviderIdentityIdEncoded,
} from '../../ids/types';
import * as ids from '../../ids';
import * as claimsUtils from '../utils';
import * as tokensUtils from '../../tokens/utils';
Expand All @@ -13,6 +17,7 @@ interface ClaimLinkIdentity extends Claim {
typ: 'ClaimLinkIdentity';
iss: NodeIdEncoded;
sub: ProviderIdentityIdEncoded;
providerIdentityClaimId?: ProviderIdentityClaimId;
}

function assertClaimLinkIdentity(
Expand Down
28 changes: 8 additions & 20 deletions src/discovery/Discovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,14 +452,14 @@ class Discovery {
switch (signedClaim.payload.typ) {
case 'ClaimLinkNode':
await this.processClaimLinkNode(
signedClaim,
signedClaim as SignedClaim<ClaimLinkNode>,
nodeId,
lastProcessedCutoffTime,
);
break;
case 'ClaimLinkIdentity':
await this.processClaimLinkIdentity(
signedClaim,
signedClaim as SignedClaim<ClaimLinkIdentity>,
nodeId,
ctx,
lastProcessedCutoffTime,
Expand All @@ -476,7 +476,7 @@ class Discovery {
}

protected async processClaimLinkNode(
signedClaim: SignedClaim,
signedClaim: SignedClaim<ClaimLinkNode>,
nodeId: NodeId,
lastProcessedCutoffTime = Date.now() - this.rediscoverSkipTime,
): Promise<void> {
Expand Down Expand Up @@ -510,7 +510,7 @@ class Discovery {
},
linkedVertexNodeInfo,
{
claim: signedClaim as SignedClaim<ClaimLinkNode>,
claim: signedClaim,
meta: {},
},
);
Expand All @@ -535,7 +535,7 @@ class Discovery {
}

protected async processClaimLinkIdentity(
signedClaim: SignedClaim,
signedClaim: SignedClaim<ClaimLinkIdentity>,
nodeId: NodeId,
ctx: ContextTimed,
lastProcessedCutoffTime = Date.now() - this.rediscoverSkipTime,
Expand Down Expand Up @@ -567,20 +567,8 @@ class Discovery {
return;
}
// Need to get the corresponding claim for this
let providerIdentityClaimId: ProviderIdentityClaimId | null = null;
const identityClaims = await this.verifyIdentityClaims(
providerId,
identityId,
ctx,
);
for (const [id, claim] of Object.entries(identityClaims)) {
const issuerNodeId = nodesUtils.decodeNodeId(claim.payload.iss);
if (issuerNodeId == null) continue;
if (nodeId.equals(issuerNodeId)) {
providerIdentityClaimId = id as ProviderIdentityClaimId;
break;
}
}
const providerIdentityClaimId = signedClaim.payload
.providerIdentityClaimId as ProviderIdentityClaimId | null;
if (providerIdentityClaimId == null) {
this.logger.warn(
`Failed to get corresponding identity claim for ${providerId}:${identityId}`,
Expand All @@ -594,7 +582,7 @@ class Discovery {
},
identityInfo,
{
claim: signedClaim as SignedClaim<ClaimLinkIdentity>,
claim: signedClaim,
meta: {
providerIdentityClaimId: providerIdentityClaimId,
url: identityInfo.url,
Expand Down
15 changes: 11 additions & 4 deletions src/identities/IdentitiesManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type {
} from './types';
import type { DB, DBTransaction, KeyPath, LevelPath } from '@matrixai/db';
import type Provider from './Provider';
import type { SignedClaim } from '../claims/types';
import type { ClaimLinkIdentity } from '../claims/payloads';
import type KeyRing from '../keys/KeyRing';
import type Sigchain from '../sigchain/Sigchain';
Expand All @@ -19,6 +18,7 @@ import {
import Logger from '@matrixai/logger';
import * as identitiesErrors from './errors';
import * as identitiesEvents from './events';
import Token from '../tokens/Token';
import * as nodesUtils from '../nodes/utils';
import { promise } from '../utils';
import { encodeProviderIdentityId } from '../ids';
Expand Down Expand Up @@ -274,15 +274,22 @@ class IdentitiesManager {
sub: encodeProviderIdentityId([providerId, identityId]),
},
undefined,
async (token) => {
async (token: Token<ClaimLinkIdentity>) => {
// Publishing in the callback to avoid adding bad claims
const claim = token.toSigned();
const identitySignedClaim = await provider.publishClaim(
identityId,
claim as SignedClaim<ClaimLinkIdentity>,
claim,
);
publishedClaimProm.resolveP(identitySignedClaim);
return token;
// Append the ProviderIdentityClaimId to the token
const payload: ClaimLinkIdentity = {
...claim.payload,
providerIdentityClaimId: identitySignedClaim.id,
};
const newToken = Token.fromPayload(payload);
newToken.signWithPrivateKey(this.keyRing.keyPair);
return newToken;
},
tran,
),
Expand Down
50 changes: 40 additions & 10 deletions tests/client/handlers/gestalts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1472,13 +1472,28 @@ describe('gestaltsGestaltTrustByIdentity', () => {
iss: nodesUtils.encodeNodeId(keyRing.getNodeId()),
sub: encodeProviderIdentityId([testProvider.id, connectedIdentity]),
};
const [claimId_, claim] = await sigchain.addClaim(identityClaim);
const [claimId_, claim] = await sigchain.addClaim(
identityClaim,
undefined,
async (token: Token<ClaimLinkIdentity>) => {
// Publishing in the callback to avoid adding bad claims
const claim = token.toSigned();
const identitySignedClaim = await testProvider.publishClaim(
connectedIdentity,
claim,
);
// Append the ProviderIdentityClaimId to the token
const payload: ClaimLinkIdentity = {
...claim.payload,
providerIdentityClaimId: identitySignedClaim.id,
};
const newToken = Token.fromPayload(payload);
newToken.signWithPrivateKey(keyRing.keyPair);
return newToken;
},
);
claimId = claimId_;
nodeChainData[claimId_] = claim;
await testProvider.publishClaim(
connectedIdentity,
claim as SignedClaim<ClaimLinkIdentity>,
);
clientService = new ClientService({
tlsConfig,
logger: logger.getChild(ClientService.name),
Expand Down Expand Up @@ -1747,12 +1762,27 @@ describe('gestaltsGestaltTrustByNode', () => {
iss: nodeIdEncodedRemote,
sub: encodeProviderIdentityId([testProvider.id, connectedIdentity]),
};
const [claimId, claim] = await node.sigchain.addClaim(identityClaim);
nodeChainData[claimId] = claim;
await testProvider.publishClaim(
connectedIdentity,
claim as SignedClaim<ClaimLinkIdentity>,
const [claimId, claim] = await node.sigchain.addClaim(
identityClaim,
undefined,
async (token: Token<ClaimLinkIdentity>) => {
// Publishing in the callback to avoid adding bad claims
const claim = token.toSigned();
const identitySignedClaim = await testProvider.publishClaim(
connectedIdentity,
claim,
);
// Append the ProviderIdentityClaimId to the token
const payload: ClaimLinkIdentity = {
...claim.payload,
providerIdentityClaimId: identitySignedClaim.id,
};
const newToken = Token.fromPayload(payload);
newToken.signWithPrivateKey(node.keyRing.keyPair);
return newToken;
},
);
nodeChainData[claimId] = claim;

const keysPath = path.join(dataDir, 'keys');
const dbPath = path.join(dataDir, 'db');
Expand Down
29 changes: 22 additions & 7 deletions tests/discovery/Discovery.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import type { IdentityId, ProviderId } from '@/identities/types';
import type { Host } from '@/network/types';
import type { Key } from '@/keys/types';
import type { SignedClaim } from '../../src/claims/types';
import type { ClaimLinkIdentity } from '@/claims/payloads';
import type { NodeId } from '../../src/ids';
import type { AgentServerManifest } from '@/nodes/agent/handlers';
import type { DiscoveryQueueInfo } from '@/discovery/types';
import type { ClaimLinkIdentity } from '@/claims/payloads/claimLinkIdentity';
import fs from 'fs';
import path from 'path';
import os from 'os';
Expand All @@ -14,6 +13,7 @@ import { DB } from '@matrixai/db';
import { PromiseCancellable } from '@matrixai/async-cancellable';
import { EventAll } from '@matrixai/events';
import { AsyncIterableX as AsyncIterable } from 'ix/asynciterable';
import { Token } from '@/tokens';
import TaskManager from '@/tasks/TaskManager';
import PolykeyAgent from '@/PolykeyAgent';
import Discovery from '@/discovery/Discovery';
Expand All @@ -33,8 +33,8 @@ import * as keysUtils from '@/keys/utils';
import * as gestaltsUtils from '@/gestalts/utils';
import * as testNodesUtils from '../nodes/utils';
import TestProvider from '../identities/TestProvider';
import { encodeProviderIdentityId } from '../../src/ids';
import 'ix/add/asynciterable-operators/toarray';
import { encodeProviderIdentityId } from '../../src/ids';
import { createTLSConfig } from '../utils/tls';

describe('Discovery', () => {
Expand Down Expand Up @@ -399,10 +399,25 @@ describe('Discovery', () => {
iss: nodesUtils.encodeNodeId(nodeA.keyRing.getNodeId()),
sub: encodeProviderIdentityId([testProvider.id, identityId2]),
};
const [, signedClaim] = await nodeA.sigchain.addClaim(identityClaim);
await testProvider.publishClaim(
identityId2,
signedClaim as SignedClaim<ClaimLinkIdentity>,
await nodeA.sigchain.addClaim(
identityClaim,
undefined,
async (token: Token<ClaimLinkIdentity>) => {
// Publishing in the callback to avoid adding bad claims
const claim = token.toSigned();
const identitySignedClaim = await testProvider.publishClaim(
identityId2,
claim,
);
// Append the ProviderIdentityClaimId to the token
const payload: ClaimLinkIdentity = {
...claim.payload,
providerIdentityClaimId: identitySignedClaim.id,
};
const newToken = Token.fromPayload(payload);
newToken.signWithPrivateKey(nodeA.keyRing.keyPair);
return newToken;
},
);
// Note that eventually we would like to add in a system of revisiting
// already discovered vertices, however for now we must do this manually.
Expand Down

0 comments on commit 392615e

Please sign in to comment.