diff options
| author | Satsuki Yanagi <17376330+u1-liquid@users.noreply.github.com> | 2020-05-09 08:20:22 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-09 08:20:22 +0900 |
| commit | 234294d564f49b1926ebf4a74d418e419ea4da71 (patch) | |
| tree | e69b661b9e2e79792104e431255622bc9a0b53d1 /src | |
| parent | brotli圧縮の無効化など Resolve #6325 (#6326) (diff) | |
| download | sharkey-234294d564f49b1926ebf4a74d418e419ea4da71.tar.gz sharkey-234294d564f49b1926ebf4a74d418e419ea4da71.tar.bz2 sharkey-234294d564f49b1926ebf4a74d418e419ea4da71.zip | |
WebAuthnでログインできないのを修正 (#6327)
Resolve #6319
Diffstat (limited to 'src')
| -rwxr-xr-x | src/client/components/signin.vue | 17 | ||||
| -rw-r--r-- | src/client/pages/my-settings/2fa.vue | 23 | ||||
| -rw-r--r-- | src/client/scripts/2fa.ts | 34 |
3 files changed, 44 insertions, 30 deletions
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 @@ <mk-switch v-model="usePasswordLessLogin" @change="updatePasswordLessLogin" v-if="$store.state.i.securityKeysList.length > 0">{{ $t('passwordLessLogin') }}</mk-switch> - <mk-info warn v-if="registration && registration.error">{{ $t('something-went-wrong') }} {{ registration.error }}</mk-info> + <mk-info warn v-if="registration && registration.error">{{ $t('error') }} {{ registration.error }}</mk-info> <mk-button v-if="!registration || registration.error" @click="addSecurityKey">{{ $t('_2fa.registerKey') }}</mk-button> <ol v-if="registration && !registration.error"> <li v-if="registration.stage >= 0"> - {{ $t('activate-key') }} + {{ $t('tapSecurityKey') }} <fa icon="spinner" pulse fixed-width v-if="registration.saving && registration.stage == 0" /> </li> <li v-if="registration.stage >= 1"> @@ -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)); } |