From fb27dd066a1773bab74c0e4d319e4c941a6e67b8 Mon Sep 17 00:00:00 2001 From: CGsama Date: Wed, 16 Jun 2021 01:58:06 -0400 Subject: [PATCH] Adapt code from v12 to fix FIDO2 reg and login --- src/client/app/common/scripts/2fa.ts | 33 +++++++++++++++++++ .../common/views/components/settings/2fa.vue | 9 ++--- .../app/common/views/components/signin.vue | 11 ++----- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/client/app/common/scripts/2fa.ts b/src/client/app/common/scripts/2fa.ts index f638cce156..7c4982ff13 100644 --- a/src/client/app/common/scripts/2fa.ts +++ b/src/client/app/common/scripts/2fa.ts @@ -3,3 +3,36 @@ export function hexifyAB(buffer) { .map(item => item.toString(16).padStart(2, 0)) .join(''); } +export function byteify(data: string, encoding: 'ascii' | 'base64' | 'hex') { + switch (encoding) { + case 'ascii': + return Uint8Array.from(data, c => c.charCodeAt(0)); + case 'base64': + return Uint8Array.from( + atob( + data + .replace(/-/g, '+') + .replace(/_/g, '/') + ), + c => c.charCodeAt(0) + ); + case 'hex': + return new Uint8Array( + data + .match(/.{1,2}/g) + .map(byte => parseInt(byte, 16)) + ); + } +} + +export function hexify(buffer: ArrayBuffer) { + return Array.from(new Uint8Array(buffer)) + .reduce( + (str, byte) => str + byte.toString(16).padStart(2, '0'), + '' + ); +} + +export function stringify(buffer: ArrayBuffer) { + return String.fromCharCode(... new Uint8Array(buffer)); +} diff --git a/src/client/app/common/views/components/settings/2fa.vue b/src/client/app/common/views/components/settings/2fa.vue index 813a91b5c0..6dd771bb73 100644 --- a/src/client/app/common/views/components/settings/2fa.vue +++ b/src/client/app/common/views/components/settings/2fa.vue @@ -72,7 +72,7 @@ import Vue from 'vue'; import i18n from '../../../../i18n'; import { hostname } from '../../../../config'; -import { hexifyAB } from '../../../scripts/2fa'; +import { hexifyAB, byteify } from '../../../scripts/2fa'; function stringifyAB(buffer) { return String.fromCharCode.apply(null, new Uint8Array(buffer)); @@ -190,12 +190,7 @@ export default Vue.extend({ challengeId: registration.challengeId, stage: 0, publicKeyOptions: { - challenge: Buffer.from( - registration.challenge - .replace(/\-/g, "+") - .replace(/_/g, "/"), - 'base64' - ), + challenge: byteify(registration.challenge, 'base64'), rp: { id: hostname, name: 'Misskey' diff --git a/src/client/app/common/views/components/signin.vue b/src/client/app/common/views/components/signin.vue index bb4a6605bd..f2955c3004 100644 --- a/src/client/app/common/views/components/signin.vue +++ b/src/client/app/common/views/components/signin.vue @@ -47,7 +47,7 @@ import Vue from 'vue'; import i18n from '../../../i18n'; import { apiUrl, host } from '../../../config'; import { toUnicode } from 'punycode'; -import { hexifyAB } from '../../scripts/2fa'; +import { hexifyAB, byteify } from '../../scripts/2fa'; export default Vue.extend({ i18n: i18n('common/views/components/signin.vue'), @@ -98,14 +98,9 @@ export default Vue.extend({ this.queryingKey = true; return navigator.credentials.get({ publicKey: { - challenge: Buffer.from( - this.challengeData.challenge - .replace(/\-/g, '+') - .replace(/_/g, '/'), - 'base64' - ), + challenge: byteify(this.challengeData.challenge, 'base64'), allowCredentials: this.challengeData.securityKeys.map(key => ({ - id: Buffer.from(key.id, 'hex'), + id: byteify(key.id, 'hex'), type: 'public-key', transports: ['usb', 'nfc', 'ble', 'internal'] })),