jolocom / jolocom-lib

Library for interacting with the identity solution provided by Jolocom.
MIT License
24 stars 18 forks source link

Add support for resolving identities based on DID method prefix #327

Closed Exulansis closed 5 years ago

Exulansis commented 5 years ago

Resolves #326

mnzaki commented 5 years ago
  1. Are we ever going to need multiple registries? Multiple instances? Different classes altogether? How would that interact (ex. does it make it redundant?) with having multiple resolvers in a registry?

  2. Why is the MultiResolver interface coupled with the JolocomRegistry in a way? I mean it is not used in the IRegistry interface, and the JolocomRegistry constructor explicitly expects a MultiResolver (as opposed to an abstract IResolver or something). I'm not entirely sure, but I think every registry (or at least a majority) is going to need access to a resolver, in which case it would make sense to add that to IRegistryStaticCreationArgs or something

mnzaki commented 5 years ago

If the client application is interacting with different DID methods then they probably will need to use the library specific to each one. Should jolocom-lib really be responsible for supporting other methods? It makes sense to be able to resolve other methods as well though, just so we can do things with their documents, for interop purposes, but it feels like an external responsibility.

With this in mind, perhaps a much simpler interface can be sufficient? Simply passing a resolver: (did: string) => IDidDocumentAttrs | null argument to the registry, which if provided will be tried first to resolve everything (regardless of method). If it returns null, the registry itself tries to resolve the DID (using just its own method). This would allow for other uses (besides multi-method support) as well, like for example resolving some special DIDs locally or through a cache and falling back to the registry otherwise.

mnzaki commented 5 years ago

More thoughts on this: the registry itself never actually needs to resolve a non-jolo DID, as far as I could tell. It's the identityWallet that needs to potentially resolve other methods some times. Perhaps the mult-did-resolve concern should be in the identityWallet?

Exulansis commented 5 years ago

More thoughts on this: the registry itself never actually needs to resolve a non-jolo DID, as far as I could tell. It's the identityWallet that needs to potentially resolve other methods some times. Perhaps the mult-did-resolve concern should be in the identityWallet?

Agree, as we are introducing the resolver, it becomes quite clear that the Registry should not need to handle any resolution (besides when making sure that the identity being created / modified exists / does not exist). There's a comment on the resolve method of the registry that this API call will be deprecated soon in favor of a resolver.

For now I've tried to keep the public API the same, to introduce no breaking changes at early stages. But we should decide on how the multi resolver is exposed to the user.

mnzaki commented 5 years ago

From the session we had today:

mnzaki commented 5 years ago

Testing out the interface diff script on this:

diff -U 3 -r develop/js/identity/didDocument/didDocument.d.ts 274ac95/js/identity/didDocument/didDocument.d.ts
--- develop/js/identity/didDocument/didDocument.d.ts    2019-08-29 13:55:52.000000000 +0200
+++ 274ac95/js/identity/didDocument/didDocument.d.ts    2019-08-29 14:30:14.000000000 +0200
@@ -31,7 +31,7 @@
     addPublicKeySection(section: PublicKeySection): void;
     addServiceEndpoint(endpoint: ServiceEndpointsSection): void;
     resetServiceEndpoints(): void;
-    static fromPublicKey(publicKey: Buffer): Promise<DidDocument>;
+    static fromPublicKey(publicKey: Buffer, didBuilder?: import("../../utils/crypto").DidBuilder): DidDocument;
     sign(vaultedKeyProvider: IVaultedKeyProvider, derivationArgs: IKeyDerivationArgs, keyId: string): Promise<void>;
     digest(): Promise<Buffer>;
     normalize(): Promise<string>;
diff -U 3 -r develop/js/identityWallet/identityWallet.d.ts 274ac95/js/identityWallet/identityWallet.d.ts
--- develop/js/identityWallet/identityWallet.d.ts   2019-08-29 13:55:52.000000000 +0200
+++ 274ac95/js/identityWallet/identityWallet.d.ts   2019-08-29 14:30:13.000000000 +0200
@@ -8,8 +8,9 @@
 import { CredentialRequest } from '../interactionTokens/credentialRequest';
 import { IKeyMetadata, ISignedCredCreationArgs } from '../credentials/signedCredential/types';
 import { ITransactionEncodable } from '../contracts/types';
-import { IRegistry } from '../registries/types';
 import { CredentialOfferRequest } from '../interactionTokens/credentialOfferRequest';
+import { MultiResolver } from '../resolver';
+import { DidDocument } from '../identity/didDocument/didDocument';
 export declare class IdentityWallet {
     private _identity;
     private _publicKeyMetadata;
@@ -18,7 +19,7 @@
     private _contractsGateway;
     did: string;
     identity: Identity;
-    didDocument: import("../identity/didDocument/didDocument").DidDocument;
+    didDocument: DidDocument;
     publicKeyMetadata: IKeyMetadata;
     private vaultedKeyProvider;
     constructor({ identity, publicKeyMetadata, vaultedKeyProvider, contractsGateway, contractsAdapter, }: IIdentityWalletCreateArgs);
@@ -33,7 +34,7 @@
     private createPaymentReq;
     private createPaymentResp;
     private initializeAndSign;
-    validateJWT<T extends JWTEncodable, A extends JWTEncodable>(receivedJWT: JSONWebToken<T>, sendJWT?: JSONWebToken<A>, customRegistry?: IRegistry): Promise<void>;
+    validateJWT<T extends JWTEncodable, A extends JWTEncodable>(receivedJWT: JSONWebToken<T>, sendJWT?: JSONWebToken<A>, resolver?: MultiResolver): Promise<void>;
     private sendTransaction;
     transactions: {
         sendTransaction: (request: ITransactionEncodable, pass: string) => Promise<string>;
diff -U 3 -r develop/js/index.d.ts 274ac95/js/index.d.ts
--- develop/js/index.d.ts   2019-08-29 13:55:52.000000000 +0200
+++ 274ac95/js/index.d.ts   2019-08-29 14:30:14.000000000 +0200
@@ -14,8 +14,8 @@
         constraintFunctions: import("./interactionTokens/interactionTokens.types").IExposedConstraintFunctions;
         fuelKeyWithEther: typeof fuelKeyWithEther;
         getIssuerPublicKey: typeof getIssuerPublicKey;
-        validateDigestable: (toValidate: import("./linkedDataSignature/types").IDigestable, customRegistry?: import("./registries/types").IRegistry) => Promise<boolean>;
-        validateDigestables: (toValidate: import("./linkedDataSignature/types").IDigestable[], customRegistry?: import("./registries/types").IRegistry) => Promise<boolean[]>;
+        validateDigestable: (toValidate: import("./linkedDataSignature/types").IDigestable, resolver?: import("./resolver").MultiResolver) => Promise<boolean>;
+        validateDigestables: (toValidate: import("./linkedDataSignature/types").IDigestable[], resolver?: import("./resolver").MultiResolver) => Promise<boolean[]>;
     };
     KeyTypes: typeof KeyTypes;
 };
diff -U 3 -r develop/js/registries/jolocomRegistry.d.ts 274ac95/js/registries/jolocomRegistry.d.ts
--- develop/js/registries/jolocomRegistry.d.ts  2019-08-29 13:55:52.000000000 +0200
+++ 274ac95/js/registries/jolocomRegistry.d.ts  2019-08-29 14:30:14.000000000 +0200
@@ -1,21 +1,23 @@
 import { IIpfsConnector } from '../ipfs/types';
 import { IEthereumConnector } from '../ethereum/types';
 import { IdentityWallet } from '../identityWallet/identityWallet';
-import { SignedCredential } from '../credentials/signedCredential/signedCredential';
 import { Identity } from '../identity/identity';
 import { IRegistryCommitArgs, IRegistryStaticCreationArgs, IRegistry } from './types';
 import { IVaultedKeyProvider, IKeyDerivationArgs } from '../vaultedKeyProvider/types';
 import { IContractsAdapter, IContractsGateway } from '../contracts/types';
+import { ValidatingIdentityResolver } from '../resolver/types';
 export declare class JolocomRegistry implements IRegistry {
     ipfsConnector: IIpfsConnector;
     ethereumConnector: IEthereumConnector;
     contractsAdapter: IContractsAdapter;
     contractsGateway: IContractsGateway;
+    readonly resolver: ValidatingIdentityResolver;
+    private readonly didBuilder;
+    constructor(resolver: ValidatingIdentityResolver, didBuilder: any);
     create(vaultedKeyProvider: IVaultedKeyProvider, decryptionPassword: string): Promise<IdentityWallet>;
     commit(commitArgs: IRegistryCommitArgs): Promise<void>;
     resolve(did: any): Promise<Identity>;
     authenticate(vaultedKeyProvider: IVaultedKeyProvider, derivationArgs: IKeyDerivationArgs, did?: string): Promise<IdentityWallet>;
-    fetchPublicProfile(entry: string): Promise<SignedCredential>;
     private resolveSafe;
 }
 export declare const createJolocomRegistry: (configuration?: IRegistryStaticCreationArgs) => JolocomRegistry;
diff -U 3 -r develop/js/registries/types.d.ts 274ac95/js/registries/types.d.ts
--- develop/js/registries/types.d.ts    2019-08-29 13:55:52.000000000 +0200
+++ 274ac95/js/registries/types.d.ts    2019-08-29 14:30:13.000000000 +0200
@@ -4,6 +4,8 @@
 import { IVaultedKeyProvider, IKeyDerivationArgs } from '../vaultedKeyProvider/types';
 import { Identity } from '../identity/identity';
 import { IContractsAdapter, IContractsGateway } from '../contracts/types';
+import { ValidatingIdentityResolver } from '../resolver/types';
+import { DidBuilder } from '../utils/crypto';
 export interface IRegistryStaticCreationArgs {
     contracts: {
         adapter: IContractsAdapter;
@@ -11,6 +13,8 @@
     };
     ipfsConnector: IIpfsConnector;
     ethereumConnector: IEthereumConnector;
+    didResolver?: ValidatingIdentityResolver;
+    didBuilder?: DidBuilder;
 }
 export interface IRegistryCommitArgs {
     vaultedKeyProvider: IVaultedKeyProvider;
Only in 274ac95/js: resolver
diff -U 3 -r develop/js/utils/crypto.d.ts 274ac95/js/utils/crypto.d.ts
--- develop/js/utils/crypto.d.ts    2019-08-29 13:55:51.000000000 +0200
+++ 274ac95/js/utils/crypto.d.ts    2019-08-29 14:30:13.000000000 +0200
@@ -1,3 +1,8 @@
 /// <reference types="node" />
 export declare function sha256(data: Buffer): Buffer;
-export declare function publicKeyToDID(publicKey: Buffer): string;
+declare type DigestFunction = (toDigest: Buffer) => Buffer;
+export declare type DidBuilder = (publicKey: Buffer) => string;
+export declare const publicKeyToDID: (prefix: string) => (digestFunction: DigestFunction) => DidBuilder;
+export declare const publicKeyToJoloDID: DidBuilder;
+export declare const getMethodPrefixFromDid: (did: string) => string;
+export {};
diff -U 3 -r develop/js/utils/validation.d.ts 274ac95/js/utils/validation.d.ts
--- develop/js/utils/validation.d.ts    2019-08-29 13:55:52.000000000 +0200
+++ 274ac95/js/utils/validation.d.ts    2019-08-29 14:30:13.000000000 +0200
@@ -1,4 +1,5 @@
 import { IDigestable } from '../linkedDataSignature/types';
-import { IRegistry } from '../registries/types';
-export declare const validateDigestable: (toValidate: IDigestable, customRegistry?: IRegistry) => Promise<boolean>;
-export declare const validateDigestables: (toValidate: IDigestable[], customRegistry?: IRegistry) => Promise<boolean[]>;
+import { MultiResolver } from '../resolver';
+export declare const validateDigestable: (toValidate: IDigestable, resolver?: MultiResolver) => Promise<boolean>;
+export declare const validateDigestables: (toValidate: IDigestable[], resolver?: MultiResolver) => Promise<boolean[]>;
+export declare const noValidation: <T>(toValidate: T) => Promise<boolean>;