Skip to content

Commit

Permalink
feat: Create VP in OP Authenticator and allow for callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
nklomp committed Feb 18, 2023
1 parent 926e358 commit 0ed86d8
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 20 deletions.
1 change: 1 addition & 0 deletions packages/did-auth-siop-op-authenticator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@sphereon/pex": "2.0.0-unstable.5",
"@sphereon/ssi-sdk-core": "^0.8.0",
"@sphereon/ssi-types": "^0.8.0",
"@veramo/credential-w3c": "4.2.0",
"@veramo/core": "4.2.0",
"cross-fetch": "^3.1.5",
"uuid": "^8.3.2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export class DidAuthSiopOpAuthenticator implements IAgentPlugin {
supportedDidMethods: args.supportedDidMethods,
context,
})
await session.init()
await session.init(args.presentationSignCallback)
this.sessions[sessionId] = session

return session
Expand Down
84 changes: 67 additions & 17 deletions packages/did-auth-siop-op-authenticator/src/session/OpSession.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DIDDocumentSection, IIdentifier, IKey, TKeyType } from '@veramo/core'
import { DIDDocumentSection, IIdentifier, IKey, PresentationPayload, TKeyType } from '@veramo/core'
import { _ExtendedIKey, mapIdentifierKeysToDoc } from '@veramo/utils'
import {
OP,
Expand All @@ -19,8 +19,8 @@ import {
SupportedVersion,
ResolveOpts,
} from '@sphereon/did-auth-siop'
import { SubmissionRequirementMatch } from '@sphereon/pex'
import { IVerifiableCredential, IVerifiablePresentation, parseDid } from '@sphereon/ssi-types'
import { PresentationSignCallBackParams, SubmissionRequirementMatch } from '@sphereon/pex'
import { IVerifiableCredential, IVerifiablePresentation, parseDid, W3CVerifiablePresentation } from '@sphereon/ssi-types'
import { SuppliedSigner } from '@sphereon/ssi-sdk-core'
import {
IAuthRequestDetails,
Expand All @@ -34,8 +34,9 @@ import {
IRequiredContext,
PerDidResolver,
} from '../types/IDidAuthSiopOpAuthenticator'
import { Resolvable } from 'did-resolver'
import { DIDResolutionOptions, DIDResolutionResult, Resolvable } from 'did-resolver'
import { KeyAlgo } from '@sphereon/ssi-sdk-core'
import { IVerifyCredentialResult, VerifyCallback, IVerifyCallbackArgs } from '@sphereon/wellknown-dids-client'

const fetch = require('cross-fetch')

Expand All @@ -61,14 +62,17 @@ export class OpSession {
this.context = options.context
}

public async init() {
public async init(presentationSignCallback: PresentationSignCallback) {
this.op = await this.createOp(
this.identifier,
this.verificationMethodSection,
parseDid(this.identifier.did).method,
this.providedDidResolvers,
this.supportedDidMethods || [],
this.expiresIn || 6000,
{
identifier: this.identifier,
verificationMethodSection: this.verificationMethodSection,
didMethod: parseDid(this.identifier.did).method,
providedDidResolvers: this.providedDidResolvers,
supportedDidMethods: this.supportedDidMethods || [],
expiresIn: this.expiresIn || 6000,
presentationSignCallback,
},
this.context
)
}
Expand Down Expand Up @@ -260,25 +264,61 @@ export class OpSession {
return SigningAlgo.EDDSA
case 'Secp256k1':
return SigningAlgo.ES256K
case 'Secp256r1':
return SigningAlgo.ES256
// @ts-ignore
case 'RSA':
return SigningAlgo.RS256
default:
throw Error('Key type not yet supported')
}
}

private async createOp(
identifier: IIdentifier,
verificationMethodSection: DIDDocumentSection | undefined,
didMethod: string,
providedDidResolvers: PerDidResolver[],
supportedDidMethods: string[],
expiresIn: number,
{
identifier,
verificationMethodSection,
didMethod,
providedDidResolvers,
supportedDidMethods,
expiresIn,
presentationSignCallback,
wellknownDidVerifyCallback,
}: {
identifier: IIdentifier
verificationMethodSection: DIDDocumentSection | undefined
didMethod: string
providedDidResolvers?: PerDidResolver[]
supportedDidMethods: string[]
expiresIn: number
presentationSignCallback?: PresentationSignCallback
wellknownDidVerifyCallback?: VerifyCallback
},
context: IRequiredContext
): Promise<OP> {
if (!identifier.controllerKeyId) {
return Promise.reject(new Error(`No controller key found for identifier: ${identifier.did}`))
}

const keyRef = await this.getKey(identifier, verificationMethodSection, context)
const verifyCallback = wellknownDidVerifyCallback
? wellknownDidVerifyCallback
: async (): Promise<IVerifyCredentialResult> => {
return { verified: true }
}

const presentationCallback = presentationSignCallback
? presentationSignCallback
: async (args: PresentationSignCallBackParams): Promise<W3CVerifiablePresentation> => {
const presentation: PresentationPayload = args.presentation as PresentationPayload
const format = args.presentationDefinition.format
return (await context.agent.createVerifiablePresentation({
presentation,
keyRef: keyRef.kid,
fetchRemoteContexts: true,
proofFormat: format && (format.ldp || format.ldp_vp) ? 'lds' : 'jwt',
})) as W3CVerifiablePresentation
}

const builder = OP.builder()
.withExpiresIn(expiresIn)
Expand All @@ -296,11 +336,21 @@ export class OpSession {
},
})
.response(ResponseMode.POST)
.addVerifyCallback((args: IVerifyCallbackArgs) => verifyCallback(args))
.withPresentationSignCallback(presentationCallback)
if (supportedDidMethods && supportedDidMethods.length > 0) {
supportedDidMethods.forEach((method) => builder.addDidMethod(method))
}
if (providedDidResolvers && providedDidResolvers.length > 0) {
providedDidResolvers.forEach((providedResolver) => builder.addResolver(providedResolver.didMethod, providedResolver.resolver))
} else {
class Resolver implements Resolvable {
async resolve(didUrl: string, options?: DIDResolutionOptions): Promise<DIDResolutionResult> {
return await context.agent.resolveDid({ didUrl, options })
}
}

builder.customResolver = new Resolver()
}

return builder.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
IKeyManager,
IDataStoreORM,
FindCredentialsArgs,
ICredentialIssuer,
} from '@veramo/core'
import { IPresentation, IVerifiableCredential } from '@sphereon/ssi-types'
import { OpSession } from '../session/OpSession'
Expand All @@ -18,6 +19,7 @@ import {
VerifiablePresentationTypeFormat,
PresentationSignCallback,
} from '@sphereon/did-auth-siop'
import { VerifyCallback } from '@sphereon/wellknown-dids-client'

import { Resolvable } from 'did-resolver'

Expand Down Expand Up @@ -106,6 +108,8 @@ export interface IRegisterSiopSessionArgs {
resolver?: Resolvable
perDidResolvers?: PerDidResolver[]
supportedDidMethods?: string[]
wellKnownDidVerifyCallback: VerifyCallback
presentationSignCallback: PresentationSignCallback
sessionId?: string
expiresIn?: number
}
Expand Down Expand Up @@ -158,4 +162,4 @@ export enum events {
DID_SIOP_AUTHENTICATED = 'didSiopAuthenticated',
}

export type IRequiredContext = IAgentContext<IDataStoreORM & IResolver & IKeyManager>
export type IRequiredContext = IAgentContext<IDataStoreORM & IResolver & IKeyManager & ICredentialIssuer>
1 change: 0 additions & 1 deletion packages/ssi-types/src/mapper/credential-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
import jwt_decode from 'jwt-decode'
import { ObjectUtils } from '../utils'


export class CredentialMapper {
static decodeVerifiablePresentation(presentation: OriginalVerifiablePresentation): JwtDecodedVerifiablePresentation | IVerifiablePresentation {
if (CredentialMapper.isJwtEncoded(presentation)) {
Expand Down

0 comments on commit 0ed86d8

Please sign in to comment.