Skip to content
This repository has been archived by the owner on Nov 20, 2024. It is now read-only.

Commit

Permalink
feat: add jwt utils
Browse files Browse the repository at this point in the history
  • Loading branch information
DanSnow committed Apr 22, 2024
1 parent 4607e32 commit 7659827
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/silent-moons-boil.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@storipress/karbon-utils': minor
---

feat: add jwt utils
46 changes: 46 additions & 0 deletions packages/karbon-utils/src/__tests__/jwt.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import '../crypto-polyfill'
import { describe, expect } from 'vitest'
import { fc, it } from '@fast-check/vitest'
import { createEncryptJWT, decryptJWT, textToUint8Array, uint8ArrayToText } from '../jwt'

describe('createEncryptJWT', () => {
// Returns an encrypted JWT string when given a valid key and plaintext
it('should return an encrypted JWT string when given a valid key and plaintext', async () => {
const key = new Uint8Array(32)
const plaintext = 'Hello, world!'
const result = await createEncryptJWT(key, plaintext)
expect(typeof result).toBe('string')
})

// Returns an error when given a key of incorrect length
it('should return an error when given a key of incorrect length', async () => {
const key = new Uint8Array(16)
const plaintext = 'Hello, world!'
await expect(createEncryptJWT(key, plaintext)).rejects.toThrowError()
})
})

describe('createEncryptJWT & decryptJWT', () => {
it.prop({ plaintext: fc.string(), key: fc.uint8Array({ minLength: 32, maxLength: 32 }) })(
'can encrypt and decrypt',
async ({ plaintext, key }) => {
const result = await createEncryptJWT(key, plaintext)

expect(typeof result).toBe('string')

expect(result).not.toBe(plaintext)

const decrypted = await decryptJWT(key, result)

expect(decrypted).toBe(plaintext)
},
)
})

describe('textToUint8Array & uint8ArrayToText', () => {
it.prop({ text: fc.string() })('can convert text to and from uint8array', ({ text }) => {
const array = textToUint8Array(text)
const result = uint8ArrayToText(array)
expect(result).toBe(text)
})
})
24 changes: 24 additions & 0 deletions packages/karbon-utils/src/jwt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { CompactEncrypt, compactDecrypt } from '@storipress/jose-browser'

export async function createEncryptJWT(key: Uint8Array, plaintext: string) {
const compactEncrypt = new CompactEncrypt(textToUint8Array(plaintext)).setProtectedHeader({
enc: 'A256GCM',
alg: 'dir',
})
return await compactEncrypt.encrypt(key)
}

export async function decryptJWT(key: Uint8Array, jwt: string) {
const { plaintext } = await compactDecrypt(jwt, key)
return uint8ArrayToText(plaintext)
}

export function textToUint8Array(text: string) {
const encoder = new TextEncoder()
return encoder.encode(text)
}

export function uint8ArrayToText(array: Uint8Array) {
const decoder = new TextDecoder()
return decoder.decode(array)
}

0 comments on commit 7659827

Please sign in to comment.