From c8c492572a0f72c6d9b8795a4e37621b5f49d2b9 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Thu, 15 Apr 2021 21:34:26 -0700 Subject: Rename toUint8Array to stringToArrayBuffer --- packages/browser/src/helpers/stringToArrayBuffer.ts | 7 +++++++ packages/browser/src/helpers/toUint8Array.ts | 7 ------- packages/browser/src/methods/startAssertion.test.ts | 10 +++++----- packages/browser/src/methods/startAttestation.test.ts | 6 +++--- packages/browser/src/methods/startAttestation.ts | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) create mode 100644 packages/browser/src/helpers/stringToArrayBuffer.ts delete mode 100644 packages/browser/src/helpers/toUint8Array.ts (limited to 'packages/browser/src') diff --git a/packages/browser/src/helpers/stringToArrayBuffer.ts b/packages/browser/src/helpers/stringToArrayBuffer.ts new file mode 100644 index 0000000..e3edd41 --- /dev/null +++ b/packages/browser/src/helpers/stringToArrayBuffer.ts @@ -0,0 +1,7 @@ +/** + * A helper method to convert an arbitrary string sent from the server to a Uint8Array the + * authenticator will expect. + */ +export default function stringToArrayBuffer(value: string): ArrayBuffer { + return new TextEncoder().encode(value); +} diff --git a/packages/browser/src/helpers/toUint8Array.ts b/packages/browser/src/helpers/toUint8Array.ts deleted file mode 100644 index 1e2243f..0000000 --- a/packages/browser/src/helpers/toUint8Array.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * A helper method to convert an arbitrary string sent from the server to a Uint8Array the - * authenticator will expect. - */ -export default function toUint8Array(value: string): Uint8Array { - return new TextEncoder().encode(value); -} diff --git a/packages/browser/src/methods/startAssertion.test.ts b/packages/browser/src/methods/startAssertion.test.ts index c077219..83c5a8b 100644 --- a/packages/browser/src/methods/startAssertion.test.ts +++ b/packages/browser/src/methods/startAssertion.test.ts @@ -6,7 +6,7 @@ import { } from '@simplewebauthn/typescript-types'; import supportsWebauthn from '../helpers/supportsWebauthn'; -import toUint8Array from '../helpers/toUint8Array'; +import stringToArrayBuffer from '../helpers/stringToArrayBuffer'; import bufferToBase64URLString from '../helpers/bufferToBase64URLString'; import startAssertion from './startAssertion'; @@ -23,7 +23,7 @@ const mockUserHandle = 'mockUserHandle'; // With ASCII challenge const goodOpts1: PublicKeyCredentialRequestOptionsJSON = { - challenge: bufferToBase64URLString(toUint8Array('fizz')), + challenge: bufferToBase64URLString(stringToArrayBuffer('fizz')), allowCredentials: [ { id: 'C0VGlvYFratUdAV1iCw-ULpUW8E-exHPXQChBfyVeJZCMfjMFcwDmOFgoMUz39LoMtCJUBW8WPlLkGT6q8qTCg', @@ -36,7 +36,7 @@ const goodOpts1: PublicKeyCredentialRequestOptionsJSON = { // With UTF-8 challenge const goodOpts2UTF8: PublicKeyCredentialRequestOptionsJSON = { - challenge: bufferToBase64URLString(toUint8Array('やれやれだぜ')), + challenge: bufferToBase64URLString(stringToArrayBuffer('やれやれだぜ')), allowCredentials: [], timeout: 1, }; @@ -78,7 +78,7 @@ test('should convert options before passing to navigator.credentials.get(...)', test('should support optional allowCredential', async () => { await startAssertion({ - challenge: bufferToBase64URLString(toUint8Array('fizz')), + challenge: bufferToBase64URLString(stringToArrayBuffer('fizz')), timeout: 1, }); @@ -87,7 +87,7 @@ test('should support optional allowCredential', async () => { test('should convert allow allowCredential to undefined when empty', async () => { await startAssertion({ - challenge: bufferToBase64URLString(toUint8Array('fizz')), + challenge: bufferToBase64URLString(stringToArrayBuffer('fizz')), timeout: 1, allowCredentials: [], }); diff --git a/packages/browser/src/methods/startAttestation.test.ts b/packages/browser/src/methods/startAttestation.test.ts index b4cfa52..0b77743 100644 --- a/packages/browser/src/methods/startAttestation.test.ts +++ b/packages/browser/src/methods/startAttestation.test.ts @@ -5,7 +5,7 @@ import { PublicKeyCredentialCreationOptionsJSON, } from '@simplewebauthn/typescript-types'; -import toUint8Array from '../helpers/toUint8Array'; +import stringToArrayBuffer from '../helpers/stringToArrayBuffer'; import supportsWebauthn from '../helpers/supportsWebauthn'; import bufferToBase64URLString from '../helpers/bufferToBase64URLString'; @@ -20,7 +20,7 @@ const mockAttestationObject = 'mockAtte'; const mockClientDataJSON = 'mockClie'; const goodOpts1: PublicKeyCredentialCreationOptionsJSON = { - challenge: bufferToBase64URLString(toUint8Array('fizz')), + challenge: bufferToBase64URLString(stringToArrayBuffer('fizz')), attestation: 'direct', pubKeyCredParams: [ { @@ -90,7 +90,7 @@ test('should return base64url-encoded response values', async done => { return new Promise(resolve => { resolve({ id: 'foobar', - rawId: toUint8Array('foobar'), + rawId: stringToArrayBuffer('foobar'), response: { attestationObject: Buffer.from(mockAttestationObject, 'ascii'), clientDataJSON: Buffer.from(mockClientDataJSON, 'ascii'), diff --git a/packages/browser/src/methods/startAttestation.ts b/packages/browser/src/methods/startAttestation.ts index 22ebe64..5601581 100644 --- a/packages/browser/src/methods/startAttestation.ts +++ b/packages/browser/src/methods/startAttestation.ts @@ -4,7 +4,7 @@ import { AttestationCredentialJSON, } from '@simplewebauthn/typescript-types'; -import toUint8Array from '../helpers/toUint8Array'; +import stringToArrayBuffer from '../helpers/stringToArrayBuffer'; import bufferToBase64URLString from '../helpers/bufferToBase64URLString'; import base64URLStringToBuffer from '../helpers/base64URLStringToBuffer'; import supportsWebauthn from '../helpers/supportsWebauthn'; @@ -28,7 +28,7 @@ export default async function startAttestation( challenge: base64URLStringToBuffer(creationOptionsJSON.challenge), user: { ...creationOptionsJSON.user, - id: toUint8Array(creationOptionsJSON.user.id), + id: stringToArrayBuffer(creationOptionsJSON.user.id), }, excludeCredentials: creationOptionsJSON.excludeCredentials.map(toPublicKeyCredentialDescriptor), }; -- cgit v1.2.3 From 032e8cb32467c140e945dd71b868828b9fb4a259 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Thu, 15 Apr 2021 21:35:05 -0700 Subject: Add bufferToUTF8String --- packages/browser/src/helpers/bufferToUTF8String.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 packages/browser/src/helpers/bufferToUTF8String.ts (limited to 'packages/browser/src') diff --git a/packages/browser/src/helpers/bufferToUTF8String.ts b/packages/browser/src/helpers/bufferToUTF8String.ts new file mode 100644 index 0000000..a4b97c9 --- /dev/null +++ b/packages/browser/src/helpers/bufferToUTF8String.ts @@ -0,0 +1,7 @@ +/** + * A helper method to convert an arbitrary ArrayBuffer, returned from an authenticator, to a UTF-8 + * string. + */ +export default function bufferToUTF8String(value: ArrayBuffer): string { + return new TextDecoder('utf-8').decode(value); +} -- cgit v1.2.3 From 1a4c8ab2ab4bcb27b83b2be6d8d0fddaaa56ba50 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Thu, 15 Apr 2021 21:37:46 -0700 Subject: Convert assertion userHandle back to UTF-8 string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the opposite of how `user.id` is converted to an ArrayBuffer prior to being passed into `navigator.credentials.create()`, so when this value is returned to the RP in an assertion it will now look like the string value originally specified in attestation options, instead of the base64url-encoded version of that string “for some reason”. --- packages/browser/jest-environment.js | 8 ++++++++ packages/browser/src/methods/startAssertion.test.ts | 2 +- packages/browser/src/methods/startAssertion.ts | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'packages/browser/src') diff --git a/packages/browser/jest-environment.js b/packages/browser/jest-environment.js index c3a9135..3d33072 100644 --- a/packages/browser/jest-environment.js +++ b/packages/browser/jest-environment.js @@ -16,6 +16,14 @@ class CustomTestEnvironment extends Environment { const { TextEncoder } = require('util'); this.global.TextEncoder = TextEncoder; } + + /** + * Add support for TextDecoder to JSDOM + */ + if (typeof this.global.TextDecoder === 'undefined') { + const { TextDecoder } = require('util'); + this.global.TextDecoder = TextDecoder; + } } } diff --git a/packages/browser/src/methods/startAssertion.test.ts b/packages/browser/src/methods/startAssertion.test.ts index 83c5a8b..a17c160 100644 --- a/packages/browser/src/methods/startAssertion.test.ts +++ b/packages/browser/src/methods/startAssertion.test.ts @@ -120,7 +120,7 @@ test('should return base64url-encoded response values', async done => { expect(response.response.authenticatorData).toEqual('bW9ja0F1dGhlbnRpY2F0b3JEYXRh'); expect(response.response.clientDataJSON).toEqual('bW9ja0NsaWVudERhdGFKU09O'); expect(response.response.signature).toEqual('bW9ja1NpZ25hdHVyZQ'); - expect(response.response.userHandle).toEqual('bW9ja1VzZXJIYW5kbGU'); + expect(response.response.userHandle).toEqual('mockUserHandle'); done(); }); diff --git a/packages/browser/src/methods/startAssertion.ts b/packages/browser/src/methods/startAssertion.ts index fa25f47..786d55b 100644 --- a/packages/browser/src/methods/startAssertion.ts +++ b/packages/browser/src/methods/startAssertion.ts @@ -6,6 +6,7 @@ import { import bufferToBase64URLString from '../helpers/bufferToBase64URLString'; import base64URLStringToBuffer from '../helpers/base64URLStringToBuffer'; +import bufferToUTF8String from '../helpers/bufferToUTF8String'; import supportsWebauthn from '../helpers/supportsWebauthn'; import toPublicKeyCredentialDescriptor from '../helpers/toPublicKeyCredentialDescriptor'; @@ -46,7 +47,7 @@ export default async function startAssertion( let userHandle = undefined; if (response.userHandle) { - userHandle = bufferToBase64URLString(response.userHandle); + userHandle = bufferToUTF8String(response.userHandle); } // Convert values to base64 to make it easier to send back to the server -- cgit v1.2.3 From fb732e401eaf1a9a0d1ff65fcb29343de201c140 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Thu, 15 Apr 2021 21:49:14 -0700 Subject: Unify naming convention of string<->buffer helpers --- packages/browser/src/helpers/stringToArrayBuffer.ts | 7 ------- packages/browser/src/helpers/utf8StringToBuffer.ts | 7 +++++++ packages/browser/src/methods/startAssertion.test.ts | 10 +++++----- packages/browser/src/methods/startAttestation.test.ts | 6 +++--- packages/browser/src/methods/startAttestation.ts | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) delete mode 100644 packages/browser/src/helpers/stringToArrayBuffer.ts create mode 100644 packages/browser/src/helpers/utf8StringToBuffer.ts (limited to 'packages/browser/src') diff --git a/packages/browser/src/helpers/stringToArrayBuffer.ts b/packages/browser/src/helpers/stringToArrayBuffer.ts deleted file mode 100644 index e3edd41..0000000 --- a/packages/browser/src/helpers/stringToArrayBuffer.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * A helper method to convert an arbitrary string sent from the server to a Uint8Array the - * authenticator will expect. - */ -export default function stringToArrayBuffer(value: string): ArrayBuffer { - return new TextEncoder().encode(value); -} diff --git a/packages/browser/src/helpers/utf8StringToBuffer.ts b/packages/browser/src/helpers/utf8StringToBuffer.ts new file mode 100644 index 0000000..32cb717 --- /dev/null +++ b/packages/browser/src/helpers/utf8StringToBuffer.ts @@ -0,0 +1,7 @@ +/** + * A helper method to convert an arbitrary string sent from the server to an ArrayBuffer the + * authenticator will expect. + */ +export default function utf8StringToBuffer(value: string): ArrayBuffer { + return new TextEncoder().encode(value); +} diff --git a/packages/browser/src/methods/startAssertion.test.ts b/packages/browser/src/methods/startAssertion.test.ts index a17c160..f005a26 100644 --- a/packages/browser/src/methods/startAssertion.test.ts +++ b/packages/browser/src/methods/startAssertion.test.ts @@ -6,7 +6,7 @@ import { } from '@simplewebauthn/typescript-types'; import supportsWebauthn from '../helpers/supportsWebauthn'; -import stringToArrayBuffer from '../helpers/stringToArrayBuffer'; +import utf8StringToBuffer from '../helpers/utf8StringToBuffer'; import bufferToBase64URLString from '../helpers/bufferToBase64URLString'; import startAssertion from './startAssertion'; @@ -23,7 +23,7 @@ const mockUserHandle = 'mockUserHandle'; // With ASCII challenge const goodOpts1: PublicKeyCredentialRequestOptionsJSON = { - challenge: bufferToBase64URLString(stringToArrayBuffer('fizz')), + challenge: bufferToBase64URLString(utf8StringToBuffer('fizz')), allowCredentials: [ { id: 'C0VGlvYFratUdAV1iCw-ULpUW8E-exHPXQChBfyVeJZCMfjMFcwDmOFgoMUz39LoMtCJUBW8WPlLkGT6q8qTCg', @@ -36,7 +36,7 @@ const goodOpts1: PublicKeyCredentialRequestOptionsJSON = { // With UTF-8 challenge const goodOpts2UTF8: PublicKeyCredentialRequestOptionsJSON = { - challenge: bufferToBase64URLString(stringToArrayBuffer('やれやれだぜ')), + challenge: bufferToBase64URLString(utf8StringToBuffer('やれやれだぜ')), allowCredentials: [], timeout: 1, }; @@ -78,7 +78,7 @@ test('should convert options before passing to navigator.credentials.get(...)', test('should support optional allowCredential', async () => { await startAssertion({ - challenge: bufferToBase64URLString(stringToArrayBuffer('fizz')), + challenge: bufferToBase64URLString(utf8StringToBuffer('fizz')), timeout: 1, }); @@ -87,7 +87,7 @@ test('should support optional allowCredential', async () => { test('should convert allow allowCredential to undefined when empty', async () => { await startAssertion({ - challenge: bufferToBase64URLString(stringToArrayBuffer('fizz')), + challenge: bufferToBase64URLString(utf8StringToBuffer('fizz')), timeout: 1, allowCredentials: [], }); diff --git a/packages/browser/src/methods/startAttestation.test.ts b/packages/browser/src/methods/startAttestation.test.ts index 0b77743..244a4d2 100644 --- a/packages/browser/src/methods/startAttestation.test.ts +++ b/packages/browser/src/methods/startAttestation.test.ts @@ -5,7 +5,7 @@ import { PublicKeyCredentialCreationOptionsJSON, } from '@simplewebauthn/typescript-types'; -import stringToArrayBuffer from '../helpers/stringToArrayBuffer'; +import utf8StringToBuffer from '../helpers/utf8StringToBuffer'; import supportsWebauthn from '../helpers/supportsWebauthn'; import bufferToBase64URLString from '../helpers/bufferToBase64URLString'; @@ -20,7 +20,7 @@ const mockAttestationObject = 'mockAtte'; const mockClientDataJSON = 'mockClie'; const goodOpts1: PublicKeyCredentialCreationOptionsJSON = { - challenge: bufferToBase64URLString(stringToArrayBuffer('fizz')), + challenge: bufferToBase64URLString(utf8StringToBuffer('fizz')), attestation: 'direct', pubKeyCredParams: [ { @@ -90,7 +90,7 @@ test('should return base64url-encoded response values', async done => { return new Promise(resolve => { resolve({ id: 'foobar', - rawId: stringToArrayBuffer('foobar'), + rawId: utf8StringToBuffer('foobar'), response: { attestationObject: Buffer.from(mockAttestationObject, 'ascii'), clientDataJSON: Buffer.from(mockClientDataJSON, 'ascii'), diff --git a/packages/browser/src/methods/startAttestation.ts b/packages/browser/src/methods/startAttestation.ts index 5601581..379e295 100644 --- a/packages/browser/src/methods/startAttestation.ts +++ b/packages/browser/src/methods/startAttestation.ts @@ -4,7 +4,7 @@ import { AttestationCredentialJSON, } from '@simplewebauthn/typescript-types'; -import stringToArrayBuffer from '../helpers/stringToArrayBuffer'; +import utf8StringToBuffer from '../helpers/utf8StringToBuffer'; import bufferToBase64URLString from '../helpers/bufferToBase64URLString'; import base64URLStringToBuffer from '../helpers/base64URLStringToBuffer'; import supportsWebauthn from '../helpers/supportsWebauthn'; @@ -28,7 +28,7 @@ export default async function startAttestation( challenge: base64URLStringToBuffer(creationOptionsJSON.challenge), user: { ...creationOptionsJSON.user, - id: stringToArrayBuffer(creationOptionsJSON.user.id), + id: utf8StringToBuffer(creationOptionsJSON.user.id), }, excludeCredentials: creationOptionsJSON.excludeCredentials.map(toPublicKeyCredentialDescriptor), }; -- cgit v1.2.3