From 59672b639f8441f0b478316e21078925e643da7b Mon Sep 17 00:00:00 2001 From: Marco Montalbano Date: Mon, 15 Apr 2024 16:51:16 +0200 Subject: [PATCH] fix: encodeBase64URLSafe replaces the base64 instead of the payload --- packages/js-auth/src/utils/base64.spec.ts | 108 +++++++++++++--------- packages/js-auth/src/utils/base64.ts | 5 +- 2 files changed, 69 insertions(+), 44 deletions(-) diff --git a/packages/js-auth/src/utils/base64.spec.ts b/packages/js-auth/src/utils/base64.spec.ts index 96304ff..18b9238 100644 --- a/packages/js-auth/src/utils/base64.spec.ts +++ b/packages/js-auth/src/utils/base64.spec.ts @@ -1,3 +1,4 @@ +import { vi } from 'vitest' import { decodeBase64URLSafe, encodeBase64URLSafe } from './base64.js' const stringifiedObject = JSON.stringify({ @@ -7,61 +8,84 @@ const stringifiedObject = JSON.stringify({ } }) -describe('encodeBase64UrlSafe', () => { - it('should be able to create a Base64 URL safe encoded ASCII string from a binary string.', () => { - expect(encodeBase64URLSafe('')).toEqual('') - expect(encodeBase64URLSafe('Hello, world')).toEqual('SGVsbG8sIHdvcmxk') - - expect(encodeBase64URLSafe(stringifiedObject)).toEqual( - 'eyJjdXN0b21lciI6eyJmaXJzdF9uYW1lIjoiSm9obiIsImxhc3RfbmFtZSI6IkRvZSJ9fQ' - ) +describe('Using `Buffer`', () => { + runTests() +}) - expect( - encodeBase64URLSafe( - '0\x82\x0760\x82\x06\x1E \x03\x02\x01\x02\x02\x10\tW¸\x13HxölÈÐ×\x12¨Ìµú0' - ) - ).toEqual('MIIHNjCCBh6gAwIBAgIQCVe4E0h49mzI0NcSqMy1-jA') +describe('Using `btoa` and `atob`', () => { + beforeAll(() => { + vi.stubGlobal('window', { + atob: globalThis.atob, + btoa: globalThis.btoa + }) + }) - expect(encodeBase64URLSafe('subjects?_d=1')).toEqual('c3ViamVjdHM_X2Q9MQ') + afterAll(() => { + vi.unstubAllGlobals() }) + + runTests() }) -describe('decodeBase64UrlSafe', () => { - it('should be able to decode a string of data which has been encoded using Base64 encoding.', () => { - expect(decodeBase64URLSafe('')).toEqual('') - expect(decodeBase64URLSafe('SGVsbG8sIHdvcmxk')).toEqual('Hello, world') +function runTests(): void { + describe('encodeBase64UrlSafe', () => { + it('should be able to create a Base64 URL safe encoded ASCII string from a binary string.', () => { + expect(encodeBase64URLSafe('')).toEqual('') + expect(encodeBase64URLSafe('Hello, world')).toEqual('SGVsbG8sIHdvcmxk') - expect( - decodeBase64URLSafe( - 'eyJjdXN0b21lciI6eyJmaXJzdF9uYW1lIjoiSm9obiIsImxhc3RfbmFtZSI6IkRvZSJ9fQ==' + expect(encodeBase64URLSafe(stringifiedObject)).toEqual( + 'eyJjdXN0b21lciI6eyJmaXJzdF9uYW1lIjoiSm9obiIsImxhc3RfbmFtZSI6IkRvZSJ9fQ' ) - ).toEqual(stringifiedObject) - expect( - decodeBase64URLSafe('MIIHNjCCBh6gAwIBAgIQCVe4E0h49mzI0NcSqMy1+jA=') - ).toEqual( - '0\x82\x0760\x82\x06\x1E \x03\x02\x01\x02\x02\x10\tW¸\x13HxölÈÐ×\x12¨Ìµú0' - ) + expect( + encodeBase64URLSafe( + '0\x82\x0760\x82\x06\x1E \x03\x02\x01\x02\x02\x10\tW¸\x13HxölÈÐ×\x12¨Ìµú0' + ) + ).toEqual('MIIHNjCCBh6gAwIBAgIQCVe4E0h49mzI0NcSqMy1-jA') - expect(decodeBase64URLSafe('c3ViamVjdHM/X2Q9MQ==')).toEqual('subjects?_d=1') + expect(encodeBase64URLSafe('subjects?_d=1')).toEqual('c3ViamVjdHM_X2Q9MQ') + }) }) - it('should be able to decode a string of data which has been encoded using Base64 URL safe encoding.', () => { - expect(decodeBase64URLSafe('')).toEqual('') - expect(decodeBase64URLSafe('SGVsbG8sIHdvcmxk')).toEqual('Hello, world') + describe('decodeBase64UrlSafe', () => { + it('should be able to decode a string of data which has been encoded using Base64 encoding.', () => { + expect(decodeBase64URLSafe('')).toEqual('') + expect(decodeBase64URLSafe('SGVsbG8sIHdvcmxk')).toEqual('Hello, world') - expect( - decodeBase64URLSafe( - 'eyJjdXN0b21lciI6eyJmaXJzdF9uYW1lIjoiSm9obiIsImxhc3RfbmFtZSI6IkRvZSJ9fQ' + expect( + decodeBase64URLSafe( + 'eyJjdXN0b21lciI6eyJmaXJzdF9uYW1lIjoiSm9obiIsImxhc3RfbmFtZSI6IkRvZSJ9fQ==' + ) + ).toEqual(stringifiedObject) + + expect( + decodeBase64URLSafe('MIIHNjCCBh6gAwIBAgIQCVe4E0h49mzI0NcSqMy1+jA=') + ).toEqual( + '0\x82\x0760\x82\x06\x1E \x03\x02\x01\x02\x02\x10\tW¸\x13HxölÈÐ×\x12¨Ìµú0' + ) + + expect(decodeBase64URLSafe('c3ViamVjdHM/X2Q9MQ==')).toEqual( + 'subjects?_d=1' ) - ).toEqual(stringifiedObject) + }) + + it('should be able to decode a string of data which has been encoded using Base64 URL safe encoding.', () => { + expect(decodeBase64URLSafe('')).toEqual('') + expect(decodeBase64URLSafe('SGVsbG8sIHdvcmxk')).toEqual('Hello, world') - expect( - decodeBase64URLSafe('MIIHNjCCBh6gAwIBAgIQCVe4E0h49mzI0NcSqMy1-jA') - ).toEqual( - '0\x82\x0760\x82\x06\x1E \x03\x02\x01\x02\x02\x10\tW¸\x13HxölÈÐ×\x12¨Ìµú0' - ) + expect( + decodeBase64URLSafe( + 'eyJjdXN0b21lciI6eyJmaXJzdF9uYW1lIjoiSm9obiIsImxhc3RfbmFtZSI6IkRvZSJ9fQ' + ) + ).toEqual(stringifiedObject) - expect(decodeBase64URLSafe('c3ViamVjdHM_X2Q9MQ')).toEqual('subjects?_d=1') + expect( + decodeBase64URLSafe('MIIHNjCCBh6gAwIBAgIQCVe4E0h49mzI0NcSqMy1-jA') + ).toEqual( + '0\x82\x0760\x82\x06\x1E \x03\x02\x01\x02\x02\x10\tW¸\x13HxölÈÐ×\x12¨Ìµú0' + ) + + expect(decodeBase64URLSafe('c3ViamVjdHM_X2Q9MQ')).toEqual('subjects?_d=1') + }) }) -}) +} diff --git a/packages/js-auth/src/utils/base64.ts b/packages/js-auth/src/utils/base64.ts index d00c88c..ea2621a 100644 --- a/packages/js-auth/src/utils/base64.ts +++ b/packages/js-auth/src/utils/base64.ts @@ -11,8 +11,9 @@ */ export function encodeBase64URLSafe(stringToEncode: string): string { if (typeof window !== 'undefined') { - return window.btoa( - stringToEncode + return ( + window + .btoa(stringToEncode) // Remove padding equal characters .replaceAll('=', '') // Replace characters according to base64url specifications