diff --git a/client/src/containers/components/SecondFactorU2F/SecondFactorU2F.ts b/client/src/containers/components/SecondFactorU2F/SecondFactorU2F.ts index d05f31a9e..fa4ecd9d4 100644 --- a/client/src/containers/components/SecondFactorU2F/SecondFactorU2F.ts +++ b/client/src/containers/components/SecondFactorU2F/SecondFactorU2F.ts @@ -51,7 +51,7 @@ async function triggerSecurityKeySigning(dispatch: Dispatch, redirectionUrl: str } try { - await redirectIfPossible(dispatch, result as Response); + await redirectIfPossible(result as Response); dispatch(securityKeySignSuccess()); await handleSuccess(dispatch, 1000); } catch (err) { @@ -59,7 +59,7 @@ async function triggerSecurityKeySigning(dispatch: Dispatch, redirectionUrl: str } } -async function redirectIfPossible(dispatch: Dispatch, res: Response) { +async function redirectIfPossible(res: Response) { if (res.status === 204) return; const body = await res.json(); diff --git a/client/src/containers/views/SecurityKeyRegistrationView/SecurityKeyRegistrationView.ts b/client/src/containers/views/SecurityKeyRegistrationView/SecurityKeyRegistrationView.ts index f51fcb45e..2bbc59967 100644 --- a/client/src/containers/views/SecurityKeyRegistrationView/SecurityKeyRegistrationView.ts +++ b/client/src/containers/views/SecurityKeyRegistrationView/SecurityKeyRegistrationView.ts @@ -2,10 +2,10 @@ import { connect } from 'react-redux'; import SecurityKeyRegistrationView from '../../../views/SecurityKeyRegistrationView/SecurityKeyRegistrationView'; import { RootState } from '../../../reducers'; import { Dispatch } from 'redux'; -import {to} from 'await-to-js'; import * as U2fApi from "u2f-api"; import { Props } from '../../../views/SecurityKeyRegistrationView/SecurityKeyRegistrationView'; import { registerSecurityKey, registerSecurityKeyFailure, registerSecurityKeySuccess } from '../../../reducers/Portal/SecurityKeyRegistration/actions'; +import AutheliaService from '../../../services/AutheliaService'; const mapStateToProps = (state: RootState) => ({ deviceRegistered: state.securityKeyRegistration.success, @@ -18,32 +18,6 @@ async function checkIdentity(token: string) { }); } -async function requestRegistration() { - return fetch('/api/u2f/register_request') - .then(async (res) => { - if (res.status !== 200) { - throw new Error('Status code ' + res.status); - } - return res.json(); - }); -} - -async function completeRegistration(response: U2fApi.RegisterResponse) { - return fetch('/api/u2f/register', { - method: 'POST', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify(response), - }) - .then(async (res) => { - if (res.status !== 200) { - throw new Error('Status code ' + res.status); - } - }); -} - function fail(dispatch: Dispatch, err: Error) { dispatch(registerSecurityKeyFailure(err.message)); } @@ -51,38 +25,22 @@ function fail(dispatch: Dispatch, err: Error) { const mapDispatchToProps = (dispatch: Dispatch, ownProps: Props) => { return { onInit: async (token: string) => { - let err, result; - dispatch(registerSecurityKey()); - [err, result] = await to(checkIdentity(token)); - if (err) { + try { + dispatch(registerSecurityKey()); + await checkIdentity(token); + const requestRegister = await AutheliaService.requestSecurityKeyRegistration(); + const registerResponse = await U2fApi.register(requestRegister, [], 60); + await AutheliaService.completeSecurityKeyRegistration(registerResponse); + dispatch(registerSecurityKeySuccess()); + setTimeout(() => { + ownProps.history.push('/'); + }, 2000); + } catch(err) { fail(dispatch, err); - return; } - [err, result] = await to(requestRegistration()); - if (err) { - fail(dispatch, err); - return; - } - - [err, result] = await to(U2fApi.register(result, [], 60)); - if (err) { - fail(dispatch, err); - return; - } - - [err, result] = await to(completeRegistration(result as U2fApi.RegisterResponse)); - if (err) { - fail(dispatch, err); - return; - } - - dispatch(registerSecurityKeySuccess()); - setTimeout(() => { - ownProps.history.push('/2fa'); - }, 2000); }, onBackClicked: () => { - ownProps.history.push('/2fa'); + ownProps.history.push('/'); } } } diff --git a/client/src/services/AutheliaService.ts b/client/src/services/AutheliaService.ts index 9d311ceaa..51f346972 100644 --- a/client/src/services/AutheliaService.ts +++ b/client/src/services/AutheliaService.ts @@ -2,6 +2,7 @@ import RemoteState from "../views/AuthenticationView/RemoteState"; import u2fApi, { SignRequest } from "u2f-api"; import Method2FA from "../types/Method2FA"; import RedirectResponse from "./RedirectResponse"; +import PreferedMethodResponse from "./PreferedMethodResponse"; class AutheliaService { static async fetchSafe(url: string, options?: RequestInit): Promise { @@ -12,7 +13,7 @@ class AutheliaService { return res; } - static async fetchSafeJson(url: string, options?: RequestInit): Promise { + static async fetchSafeJson(url: string, options?: RequestInit): Promise { const res = await fetch(url, options); if (res.status !== 200) { throw new Error('Status code ' + res.status); @@ -167,7 +168,19 @@ class AutheliaService { } static async fetchPrefered2faMethod(): Promise { - const doc = await this.fetchSafeJson('/api/secondfactor/preferences'); + const doc = await this.fetchSafeJson('/api/secondfactor/preferences'); + if (!doc) { + throw new Error("No response."); + } + + if (doc.error) { + throw new Error(doc.error); + } + + if (!doc.method) { + throw new Error("No method."); + } + return doc.method; } @@ -185,6 +198,21 @@ class AutheliaService { static async getAvailable2faMethods(): Promise { return await this.fetchSafeJson('/api/secondfactor/available'); } + + static async completeSecurityKeyRegistration(response: u2fApi.RegisterResponse): Promise { + return await this.fetchSafe('/api/u2f/register', { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify(response), + }); + } + + static async requestSecurityKeyRegistration() { + return this.fetchSafeJson('/api/u2f/register_request') + } } export default AutheliaService; \ No newline at end of file diff --git a/client/src/services/PreferedMethodResponse.ts b/client/src/services/PreferedMethodResponse.ts new file mode 100644 index 000000000..12375121f --- /dev/null +++ b/client/src/services/PreferedMethodResponse.ts @@ -0,0 +1,7 @@ +import Method2FA from "../types/Method2FA"; + + +export default interface PreferedMethodResponse { + method?: Method2FA; + error?: string; +} \ No newline at end of file