Skip to content

Commit

Permalink
fix: code improvements for valid sdjwt presentation exchange
Browse files Browse the repository at this point in the history
Signed-off-by: Francisco Javier Ribo Labrador <elribonazo@gmail.com>
  • Loading branch information
elribonazo committed Oct 29, 2024
1 parent f380b51 commit b91a4e7
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 43 deletions.
20 changes: 5 additions & 15 deletions demos/next/src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,21 +197,11 @@ export const initiatePresentationRequest = createAsyncThunk<
type
} = options;

if (type === SDK.Domain.CredentialType.JWT) {
await agent.initiatePresentationRequest<SDK.Domain.CredentialType>(
SDK.Domain.CredentialType.JWT,
toDID,
presentationClaims
);
}

if (type === SDK.Domain.CredentialType.AnonCreds) {
await agent.initiatePresentationRequest<SDK.Domain.CredentialType>(
SDK.Domain.CredentialType.AnonCreds,
toDID,
presentationClaims
);
}
await agent.initiatePresentationRequest<typeof type>(
type,
toDID,
presentationClaims
);

return api.fulfillWithValue(null)
} catch (err) {
Expand Down
4 changes: 2 additions & 2 deletions demos/next/src/components/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ export function Message({ message }) {
if (requestPresentationFormat === SDK.Domain.AttachmentFormats.PRESENTATION_EXCHANGE_DEFINITIONS) {

if (SDK.isPresentationDefinitionRequestType(requestPresentation, SDK.Domain.CredentialType.SDJWT)) {
const credentials: SDK.Domain.Credential[] = app.credentials;
const credentials: SDK.Domain.Credential[] = app.credentials.filter((c) => c instanceof SDK.SDJWTCredential);
const fields: SDK.Domain.InputField[] = requestPresentation.presentation_definition ?
requestPresentation.presentation_definition.input_descriptors.at(0)?.constraints.fields ?? [] :
[];
Expand Down Expand Up @@ -530,7 +530,7 @@ export function Message({ message }) {

if (SDK.isPresentationDefinitionRequestType(requestPresentation, SDK.Domain.CredentialType.JWT)) {

const credentials: SDK.Domain.Credential[] = app.credentials;
const credentials: SDK.Domain.Credential[] = app.credentials.filter((c) => c instanceof SDK.JWTCredential);
const fields: SDK.Domain.InputField[] = requestPresentation.presentation_definition ?
requestPresentation.presentation_definition.input_descriptors.at(0)?.constraints.fields ?? [] :
[];
Expand Down
13 changes: 9 additions & 4 deletions demos/next/src/pages/verification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,16 @@ const VerificationRequestAnoncreds: React.FC<{ onHandleInitiate: <T extends SDK.
</AgentRequire>
}

const VerificationRequestJWT: React.FC<{ onHandleInitiate: <T extends SDK.Domain.CredentialType = SDK.Domain.CredentialType.JWT>(claims: SDK.Domain.PresentationClaims<T>, type: T) => void }> = props => {
const VerificationRequestJWT: React.FC<{
onHandleInitiate: <T extends SDK.Domain.CredentialType = SDK.Domain.CredentialType.JWT>(
claims: SDK.Domain.PresentationClaims<T>,
type: T
) => void,
type: SDK.Domain.CredentialType
}> = props => {
const [presentationClaims, setPresentationClaims] = useState<SDK.Domain.PresentationClaims>();
const [requiredFields, setRequiredFields] = React.useState<string>("emailAddress=test@email.com")
const [trustIssuers, setTrustIssuers] = React.useState<string>("did:prism:a0209ebd691c5ec20636f206b3e101c726fdc1c22b9b850b4b811ac4a82e28d8")

return <AgentRequire text="In order to start a Verification request the Edge Agent needs to be started first." >
<label htmlFor="requiredJWTClaims">Required claims<span style={{ fontSize: 11 }}>(variable=value split by ,)</span></label>
<input
Expand Down Expand Up @@ -185,7 +190,7 @@ const VerificationRequestJWT: React.FC<{ onHandleInitiate: <T extends SDK.Domain
}
return all
}, {})
}, SDK.Domain.CredentialType.JWT)
}, props.type)
}}>
Initiate
</button>
Expand Down Expand Up @@ -243,7 +248,7 @@ const VerificationRequest: React.FC<{}> = props => {

{
(type === SDK.Domain.CredentialType.JWT || type === SDK.Domain.CredentialType.SDJWT) &&
<VerificationRequestJWT onHandleInitiate={onHandleInitiate} />
<VerificationRequestJWT onHandleInitiate={onHandleInitiate} type={type} />
}
{
type === SDK.Domain.CredentialType.AnonCreds &&
Expand Down
4 changes: 2 additions & 2 deletions src/domain/models/Message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,9 @@ export class Message implements Pluto.Storable {

const decodeBase64 = (data: string) => {
try {
return base64.baseDecode(data);
} catch (err) {
return base64url.baseDecode(data);
} catch (err) {
return base64.baseDecode(data);
}
}
export namespace Message {
Expand Down
6 changes: 3 additions & 3 deletions src/domain/models/VerifiableCredential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,13 +454,13 @@ export class SDJWPresentationOptions {
options: {
name?: string,
purpose?: string,
jwt?: PresentationJWTOptions
sdjwt?: PresentationJWTOptions
}
) {
this.name = options.name ?? "Presentation";
this.purpose = options.purpose ?? "Verifying Credentials";
this.sdjwt = options.jwt ?? {
jwtAlg: [JWT_ALG.ES256K],
this.sdjwt = options.sdjwt ?? {
jwtAlg: [JWT_ALG.EdDSA],
};
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/edge-agent/didcomm/CreatePresentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,7 @@ export class CreatePresentation extends Task<Presentation, Args> {
);
return JSON.stringify(presentationSubmission);
}
}
if (request.isType(Domain.AttachmentFormats.PRESENTATION_EXCHANGE_DEFINITIONS)) {

if (credential instanceof AnonCredsCredential) {
const storedLinkSecret = await ctx.Pluto.getLinkSecret();
if (!storedLinkSecret) {
Expand Down Expand Up @@ -212,6 +211,7 @@ export class CreatePresentation extends Task<Presentation, Args> {
const presentation = await ctx.Pollux.createPresentationProof(request, credential, { linkSecret });
return presentation;
}

if (credential instanceof JWTCredential && request.isType(Domain.AttachmentFormats.JWT)) {
if (!credential.isProvable()) {
throw new Error("Credential is not Provable");
Expand Down
12 changes: 5 additions & 7 deletions src/edge-agent/didcomm/CreatePresentationRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export class CreatePresentationRequest extends Task<RequestPresentation, Args> {
const didDocument = await ctx.Castor.resolveDID(toDID.toString());
const peerDIDTask = new CreatePeerDID({ services: didDocument.services, updateMediator: true });
const newPeerDID = await ctx.run(peerDIDTask);

if (type === Domain.CredentialType.AnonCreds) {
if (!validatePresentationClaims(claims, Domain.CredentialType.AnonCreds)) {
throw new Domain.PolluxError.InvalidPresentationDefinitionError("Anoncreds Claims are invalid");
Expand All @@ -42,19 +41,18 @@ export class CreatePresentationRequest extends Task<RequestPresentation, Args> {
if (!validatePresentationClaims(claims, Domain.CredentialType.SDJWT)) {
throw new Domain.PolluxError.InvalidPresentationDefinitionError("SD+JWT Claims are invalid");
}

const presentationDefinitionRequest = await ctx.Pollux.createPresentationDefinitionRequest(
type,
claims,
new Domain.PresentationOptions({
jwt: {
sdjwt: {
jwtAlg: [
Domain.curveToAlg(Domain.Curve.ED25519)
Domain.curveToAlg(Domain.Curve.SECP256K1)
]
},
challenge: "Sign this text " + uuid(),
domain: 'N/A'
})
}, type)
);
return this.createRequest(
type,
Expand All @@ -78,7 +76,7 @@ export class CreatePresentationRequest extends Task<RequestPresentation, Args> {
},
challenge: "Sign this text " + uuid(),
domain: 'N/A'
})
}, type)
);

return this.createRequest(
Expand All @@ -98,7 +96,7 @@ export class CreatePresentationRequest extends Task<RequestPresentation, Args> {
from: Domain.DID,
to: Domain.DID
) {
const attachmentFormat = type === Domain.CredentialType.JWT ?
const attachmentFormat = type === Domain.CredentialType.JWT || type === Domain.CredentialType.SDJWT ?
Domain.AttachmentFormats.PRESENTATION_EXCHANGE_DEFINITIONS :
Domain.AttachmentFormats.ANONCREDS_PROOF_REQUEST;

Expand Down
8 changes: 2 additions & 6 deletions src/pollux/Pollux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ export default class Pollux implements IPollux {
const decodedVerificationMethodBuffer = base64.baseDecode(base64VerificationMethod);
const decodedVerificationValue = Buffer.from(decodedVerificationMethodBuffer).toString();
const decodedVerificationMethod = JSON.parse(decodedVerificationValue);

if (proofType === JWTProofType.EcdsaSecp256k1Signature2019) {
const { publicKeyJwk } = decodedVerificationMethod;
const verificationMethodType = decodedVerificationMethod.type;
Expand Down Expand Up @@ -411,7 +412,7 @@ export default class Pollux implements IPollux {
}

const disclosedFields = await this.revealCredentialFields(credential, ['subject', 'sub']);
const subject = disclosedFields['subject'] || disclosedFields['sub'];
const subject = disclosedFields['subject'] || disclosedFields['sub'] || credential.subject;
const issuerDID = DID.fromString(subject);
const kid = await this.getSigningKid(issuerDID, privateKey);
let jws: string;
Expand Down Expand Up @@ -591,12 +592,10 @@ export default class Pollux implements IPollux {
const options = presentationOptions.options;

if (type === CredentialType.JWT || type === CredentialType.SDJWT) {

const jwtOptions = this.validatePresentationDefinitionOptions(
type,
options
)

if (!(options instanceof JWTPresentationOptions) && !(options instanceof SDJWPresentationOptions)) {
throw new PolluxError.InvalidPresentationDefinitionError("Options must be JWTPresentationOptions or SDJWPresentationOptions for JWT")
}
Expand Down Expand Up @@ -646,7 +645,6 @@ export default class Pollux implements IPollux {
alg: jwtOptions.jwtAlg ?? []
},
}

const inputDescriptor: InputDescriptor = {
id: uuid(),
name: options.name,
Expand All @@ -662,7 +660,6 @@ export default class Pollux implements IPollux {
} : {

}

const presentationDefinitionRequest: PresentationDefinitionRequest<typeof type> = {
presentation_definition: {
id: uuid(),
Expand All @@ -673,7 +670,6 @@ export default class Pollux implements IPollux {
},
options: presentationDefinitionOptions
}

return presentationDefinitionRequest
}

Expand Down
15 changes: 13 additions & 2 deletions src/pollux/utils/claims.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,23 @@ export function isPresentationDefinitionRequestType
): request is PresentationDefinitionRequest<Type> {


if (type === CredentialType.JWT || type === CredentialType.SDJWT) {
if (type === CredentialType.JWT) {
if (!request || !request.presentation_definition) {
return false;
}
const [format] = Object.keys(request.presentation_definition.format);
if (!format || !['jwt'].includes(format)) {
return false
}
return true;
}

if (type === CredentialType.SDJWT) {
if (!request || !request.presentation_definition) {
return false;
}
const [format] = Object.keys(request.presentation_definition.format);
if (!format || !['jwt', 'sdjwt'].includes(format)) {
if (!format || !['sdjwt'].includes(format)) {
return false
}
return true;
Expand Down

0 comments on commit b91a4e7

Please sign in to comment.