diff options
Diffstat (limited to 'packages/server/src')
-rw-r--r-- | packages/server/src/helpers/base64url.ts | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/packages/server/src/helpers/base64url.ts b/packages/server/src/helpers/base64url.ts new file mode 100644 index 0000000..c3a9c98 --- /dev/null +++ b/packages/server/src/helpers/base64url.ts @@ -0,0 +1,66 @@ +/** + * Convert from a Base64URL-encoded string to an Array Buffer. Best used when converting a + * credential ID from a JSON string to an ArrayBuffer, like in allowCredentials or + * excludeCredentials + * + * Helper method to compliment `bufferToBase64URLString` + */ +export function toBuffer(base64URLString: string): Uint8Array { + // Convert from Base64URL to Base64 + const base64 = toBase64(base64URLString); + + // Convert to a binary string + const binary = atob(base64); + + // Convert binary string to buffer + const buffer = new ArrayBuffer(binary.length); + const bytes = new Uint8Array(buffer); + + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + + return bytes; +} + +/** + * Convert the given array buffer into a Base64URL-encoded string. Ideal for converting various + * credential response ArrayBuffers to string for sending back to the server as JSON. + * + * Helper method to compliment `base64URLStringToBuffer` + */ +export function fromBuffer(buffer: Uint8Array): string { + let str = ''; + + for (const charCode of buffer) { + str += String.fromCharCode(charCode); + } + + const base64String = btoa(str); + + return base64String.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); +} + +/** + * Convert a base64url string into base64 + */ +export function toBase64(base64URLString: string): string { + const base64 = base64URLString.replace(/-/g, '+').replace(/_/g, '/'); + /** + * Pad with '=' until it's a multiple of four + * (4 - (85 % 4 = 1) = 3) % 4 = 3 padding + * (4 - (86 % 4 = 2) = 2) % 4 = 2 padding + * (4 - (87 % 4 = 3) = 1) % 4 = 1 padding + * (4 - (88 % 4 = 0) = 4) % 4 = 0 padding + */ + const padLength = (4 - (base64.length % 4)) % 4; + const padded = base64.padEnd(base64.length + padLength, '='); + + return padded; +} + +export default { + toBuffer, + fromBuffer, + toBase64, +}; |