ucan-wg/ts-ucan

encode + parse

nichoth opened this issue · 5 comments

In packages/core/src/token.ts, we have this parse function, that throws an error Expected JWT format: 3 dot-separated base64url-encoded values:

export function parse(encodedUcan: string): UcanParts {
  const [ encodedHeader, encodedPayload, signature ] = encodedUcan.split(".")

  if (encodedHeader == null || encodedPayload == null || signature == null) {
    throw new Error(`Can't parse UCAN: ${encodedUcan}: Expected JWT format: 3 dot-separated base64url-encoded values.`)
  }

But in encode.ts, we have this encode function, that returns two dot separated segments:

/**
 * Encode a UCAN.
 *
 * @param ucan The UCAN to encode
 */
export function encode(ucan: Ucan<unknown>): string { 
  return `${ucan.signedData}.${ucan.signature}`
}

Does the parse function need updating? (yarn run test failed on my machine)

It shouldn't fail because of that. ucan.signedData is initialized to a string containing a dot:

const signedData = `${encodedHeader}.${encodedPayload}`

What's the error you get when you yarn run test?

ucan.signedData is initialized to a string containing a dot

That's actually my confusion here. It is a string containing a single dot, but the error message says

3 dot-separated base64url-encoded values

For the tests, you must do npm run build (or yarn run build) first, so never mind about that; they passed for me.

It took a little while to complete the build process, so I can understand wanting to keep it as a separate command from testing.

ucan.signedData is initialized to a string containing a dot

That's actually my confusion here. It is a string containing a single dot, but the error message says

3 dot-separated base64url-encoded values

Read over my messages and the code above again :) : ucan.signedData contains a dot, and finally it gets combined with a dot and ucan.signature, which gives you a three-dots string.

I.e. if I grab all the pieces what happens is this:

// In token.sign
const signedData = `${encodedHeader}.${encodedPayload}` 
// in token.encode
return `${ucan.signedData}.${ucan.signature}`

Got it thanks!