From 234294d564f49b1926ebf4a74d418e419ea4da71 Mon Sep 17 00:00:00 2001
From: Satsuki Yanagi <17376330+u1-liquid@users.noreply.github.com>
Date: Sat, 9 May 2020 08:20:22 +0900
Subject: WebAuthnでログインできないのを修正 (#6327)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolve #6319
---
src/client/components/signin.vue | 17 ++++++-----------
src/client/pages/my-settings/2fa.vue | 23 +++++++----------------
src/client/scripts/2fa.ts | 34 +++++++++++++++++++++++++++++++---
3 files changed, 44 insertions(+), 30 deletions(-)
(limited to 'src')
diff --git a/src/client/components/signin.vue b/src/client/components/signin.vue
index b84b89a5c7..dc73ad8a0f 100755
--- a/src/client/components/signin.vue
+++ b/src/client/components/signin.vue
@@ -51,7 +51,7 @@ import MkButton from './ui/button.vue';
import MkInput from './ui/input.vue';
import i18n from '../i18n';
import { apiUrl, host } from '../config';
-import { hexifyAB } from '../scripts/2fa';
+import { byteify, hexify } from '../scripts/2fa';
export default Vue.extend({
i18n,
@@ -121,14 +121,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']
})),
@@ -143,9 +138,9 @@ export default Vue.extend({
return this.$root.api('signin', {
username: this.username,
password: this.password,
- signature: hexifyAB(credential.response.signature),
- authenticatorData: hexifyAB(credential.response.authenticatorData),
- clientDataJSON: hexifyAB(credential.response.clientDataJSON),
+ signature: hexify(credential.response.signature),
+ authenticatorData: hexify(credential.response.authenticatorData),
+ clientDataJSON: hexify(credential.response.clientDataJSON),
credentialId: credential.id,
challengeId: this.challengeData.challengeId
});
diff --git a/src/client/pages/my-settings/2fa.vue b/src/client/pages/my-settings/2fa.vue
index 1d1e111dac..6ceca21fe6 100644
--- a/src/client/pages/my-settings/2fa.vue
+++ b/src/client/pages/my-settings/2fa.vue
@@ -22,12 +22,12 @@
{{ $t('passwordLessLogin') }}
- {{ $t('something-went-wrong') }} {{ registration.error }}
+ {{ $t('error') }} {{ registration.error }}
{{ $t('_2fa.registerKey') }}
-
- {{ $t('activate-key') }}
+ {{ $t('tapSecurityKey') }}
-
@@ -67,16 +67,12 @@ import Vue from 'vue';
import { faLock } from '@fortawesome/free-solid-svg-icons';
import i18n from '../../i18n';
import { hostname } from '../../config';
-import { hexifyAB } from '../../scripts/2fa';
+import { byteify, hexify, stringify } from '../../scripts/2fa';
import MkButton from '../../components/ui/button.vue';
import MkInfo from '../../components/ui/info.vue';
import MkInput from '../../components/ui/input.vue';
import MkSwitch from '../../components/ui/switch.vue';
-function stringifyAB(buffer) {
- return String.fromCharCode.apply(null, new Uint8Array(buffer));
-}
-
export default Vue.extend({
i18n,
components: {
@@ -157,8 +153,8 @@ export default Vue.extend({
name: this.keyName,
challengeId: this.registration.challengeId,
// we convert each 16 bits to a string to serialise
- clientDataJSON: stringifyAB(this.registration.credential.response.clientDataJSON),
- attestationObject: hexifyAB(this.registration.credential.response.attestationObject)
+ clientDataJSON: stringify(this.registration.credential.response.clientDataJSON),
+ attestationObject: hexify(this.registration.credential.response.attestationObject)
}).then(key => {
this.registration = null;
key.lastUsed = new Date();
@@ -208,18 +204,13 @@ export default Vue.extend({
challengeId: registration.challengeId,
stage: 0,
publicKeyOptions: {
- challenge: Uint8Array.from(
- atob(registration.challenge
- .replace(/\-/g, '+')
- .replace(/_/g, '/')),
- x => x.charCodeAt(0),
- ),
+ challenge: byteify(registration.challenge, 'base64'),
rp: {
id: hostname,
name: 'Misskey'
},
user: {
- id: Uint8Array.from(this.$store.state.i.id, c => c.charCodeAt(0)),
+ id: byteify(this.$store.state.i.id, 'ascii'),
name: this.$store.state.i.username,
displayName: this.$store.state.i.name,
},
diff --git a/src/client/scripts/2fa.ts b/src/client/scripts/2fa.ts
index e431361aac..00363cffa6 100644
--- a/src/client/scripts/2fa.ts
+++ b/src/client/scripts/2fa.ts
@@ -1,5 +1,33 @@
-export function hexifyAB(buffer) {
+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))
- .map(item => item.toString(16).padStart(2, '0'))
- .join('');
+ .reduce(
+ (str, byte) => str + byte.toString(16).padStart(2, '0'),
+ ''
+ );
+}
+
+export function stringify(buffer: ArrayBuffer) {
+ return String.fromCharCode(... new Uint8Array(buffer));
}
--
cgit v1.2.3-freya