Skip to content

Commit

Permalink
change decode to parse and add link to jwt rfc
Browse files Browse the repository at this point in the history
  • Loading branch information
mistermoe committed Dec 8, 2023
1 parent 60874c6 commit 684d5b0
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 17 deletions.
16 changes: 9 additions & 7 deletions packages/credentials/src/compact-jwt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ export type VerifyJwtParams = {
}

/**
* Parameters for decoding a JWT.
* Parameters for parsing a JWT.
* used in {@link CompactJwt.parse}
*/
export type DecodeJwtParams = {
export type ParseJwtParams = {
compactJwt: string
}

Expand Down Expand Up @@ -65,6 +66,7 @@ const ed25519Signer: Signer<Web5Crypto.EdDsaOptions> = {
/**
* Class for handling Compact JSON Web Tokens (JWTs).
* This class provides methods to create, verify, and decode JWTs using various cryptographic algorithms.
* More information on JWTs can be found [here](https://datatracker.ietf.org/doc/html/rfc7519)
*/
export class CompactJwt {
/** supported cryptographic algorithms. keys are `${alg}:${crv}`. */
Expand Down Expand Up @@ -133,7 +135,7 @@ export class CompactJwt {
* ```
*/
static async verify(params: VerifyJwtParams) {
const { decoded: decodedJwt, encoded: encodedJwt } = CompactJwt.decode({ compactJwt: params.compactJwt });
const { decoded: decodedJwt, encoded: encodedJwt } = CompactJwt.parse({ compactJwt: params.compactJwt });
// TODO: should really be looking for verificationMethod with authentication verification relationship
const verificationMethod = await CompactJwt.didResolver.dereference({ didUrl: decodedJwt.header.kid! });
if (!utils.isVerificationMethod(verificationMethod)) { // ensure that appropriate verification method was found
Expand Down Expand Up @@ -177,13 +179,13 @@ export class CompactJwt {
}

/**
* Decodes a JWT without verifying its signature.
* Parses a JWT without verifying its signature.
* @param params - Parameters for JWT decoding, including the JWT string.
* @returns Decoded JWT parts, including header and payload.
* @returns both encoded and decoded JWT parts
* @example
* const decodedJwt = CompactJwt.decode({ compactJwt: myJwt });
* const { encoded: encodedJwt, decoded: decodedJwt } = CompactJwt.parse({ compactJwt: myJwt });
*/
static decode(params: DecodeJwtParams) {
static parse(params: ParseJwtParams) {
const splitJwt = params.compactJwt.split('.');
if (splitJwt.length !== 3) {
throw new Error(`Verification failed: Malformed JWT. expected 3 parts. got ${splitJwt.length}`);
Expand Down
2 changes: 1 addition & 1 deletion packages/credentials/src/verifiable-credential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ export class VerifiableCredential {
* ```
*/
public static parseJwt(vcJwt: string): VerifiableCredential {
const parsedJwt = CompactJwt.decode({ compactJwt: vcJwt });
const parsedJwt = CompactJwt.parse({ compactJwt: vcJwt });
const vcDataModel: VcDataModel = parsedJwt.decoded.payload['vc'];

if(!vcDataModel) {
Expand Down
19 changes: 10 additions & 9 deletions packages/credentials/tests/compact-jwt.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { expect } from 'chai';
import { JwtHeader, JwtPayload } from 'jwt-decode';

describe('CompactJwt', () => {
describe('verify', () => {
describe('parse', () => {
it('throws error if JWT doesnt contain 3 parts', async () => {
try {
await CompactJwt.verify({ compactJwt: 'abcd123' });
await CompactJwt.parse({ compactJwt: 'abcd123' });
expect.fail();
} catch(e: any) {
expect(e.message).to.include('Malformed JWT. expected 3 parts');
Expand All @@ -18,7 +18,7 @@ describe('CompactJwt', () => {

it('throws error if JWT header is not properly base64url encoded', async () => {
try {
await CompactJwt.verify({ compactJwt: 'abcd123.efgh.hijk' });
await CompactJwt.parse({ compactJwt: 'abcd123.efgh.hijk' });
expect.fail();
} catch(e: any) {
expect(e.message).to.include('Invalid base64url encoding for JWT header');
Expand All @@ -30,7 +30,7 @@ describe('CompactJwt', () => {
const base64UrlEncodedHeader = Convert.object(header).toBase64Url();

try {
await CompactJwt.verify({ compactJwt: `${base64UrlEncodedHeader}.efgh.hijk` });
await CompactJwt.parse({ compactJwt: `${base64UrlEncodedHeader}.efgh.hijk` });
expect.fail();
} catch(e: any) {
expect(e.message).to.include('typ property set to JWT');
Expand All @@ -42,7 +42,7 @@ describe('CompactJwt', () => {
const base64UrlEncodedHeader = Convert.object(header).toBase64Url();

try {
await CompactJwt.verify({ compactJwt: `${base64UrlEncodedHeader}.efgh.hijk` });
await CompactJwt.parse({ compactJwt: `${base64UrlEncodedHeader}.efgh.hijk` });
expect.fail();
} catch(e: any) {
expect(e.message).to.include('typ property set to JWT');
Expand All @@ -54,7 +54,7 @@ describe('CompactJwt', () => {
const base64UrlEncodedHeader = Convert.object(header).toBase64Url();

try {
await CompactJwt.verify({ compactJwt: `${base64UrlEncodedHeader}.efgh.hijk` });
await CompactJwt.parse({ compactJwt: `${base64UrlEncodedHeader}.efgh.hijk` });
expect.fail();
} catch(e: any) {
expect(e.message).to.include('to contain alg and kid');
Expand All @@ -66,7 +66,7 @@ describe('CompactJwt', () => {
const base64UrlEncodedHeader = Convert.object(header).toBase64Url();

try {
await CompactJwt.verify({ compactJwt: `${base64UrlEncodedHeader}.efgh.hijk` });
await CompactJwt.parse({ compactJwt: `${base64UrlEncodedHeader}.efgh.hijk` });
expect.fail();
} catch(e: any) {
expect(e.message).to.include('to contain alg and kid');
Expand All @@ -78,13 +78,14 @@ describe('CompactJwt', () => {
const base64UrlEncodedHeader = Convert.object(header).toBase64Url();

try {
await CompactJwt.verify({ compactJwt: `${base64UrlEncodedHeader}.efgh.hijk` });
await CompactJwt.parse({ compactJwt: `${base64UrlEncodedHeader}.efgh.hijk` });
expect.fail();
} catch(e: any) {
expect(e.message).to.include('Invalid base64url encoding for JWT payload');
}
});

});
describe('verify', () => {
it('throws error if JWT header kid does not dereference a verification method', async () => {
const did = await DidKeyMethod.create({ keyAlgorithm: 'secp256k1' });
const header: JwtHeader = { typ: 'JWT', alg: 'ES256K', kid: did.did };
Expand Down

0 comments on commit 684d5b0

Please sign in to comment.