From 50636587a882448bd6eb6006baef44793530dd95 Mon Sep 17 00:00:00 2001 From: Clement Michaud Date: Fri, 4 Aug 2017 21:20:31 +0200 Subject: [PATCH] Notifications to users do not use notifyjs anymore. They are more common and located in the form areas to improve visibility on mobile devices. --- Gruntfile.js | 2 +- package.json | 1 - src/client/css/01-main.css | 39 +++++++++ src/client/index.ts | 16 ++-- src/client/lib/INotifier.ts | 14 +++ src/client/lib/Notifier.ts | 45 ++++++++++ .../firstfactor/FirstFactorValidator.ts | 8 +- .../{ => lib}/firstfactor/UISelectors.ts | 0 src/client/{ => lib}/firstfactor/index.ts | 11 ++- .../{ => lib}/reset-password/constants.ts | 0 .../reset-password/reset-password-form.ts | 13 +-- .../reset-password/reset-password-request.ts | 11 ++- .../{ => lib}/secondfactor/TOTPValidator.ts | 2 +- .../{ => lib}/secondfactor/U2FValidator.ts | 15 ++-- .../{ => lib}/secondfactor/constants.ts | 0 src/client/{ => lib}/secondfactor/index.ts | 16 ++-- .../{ => lib}/totp-register/totp-register.ts | 0 .../{ => lib}/totp-register/ui-selector.ts | 0 src/client/lib/u2f-register/u2f-register.ts | 62 +++++++++++++ src/client/u2f-register/u2f-register.ts | 53 ----------- src/server/views/firstfactor.pug | 1 + src/server/views/password-reset-form.pug | 1 + src/server/views/password-reset-request.pug | 1 + src/server/views/secondfactor.pug | 2 + src/types/jquery-notify.d.ts | 4 - test/features/authentication.feature | 4 +- test/features/reset-password.feature | 4 +- test/features/restrictions.feature | 3 +- .../step_definitions/authentication.ts | 9 -- .../step_definitions/notifications.ts | 25 ++++++ test/features/support/world.ts | 27 ++++-- test/unit/client/Notifier.test.ts | 71 +++++++++++++++ .../firstfactor/FirstFactorValidator.test.ts | 22 ++--- test/unit/client/firstfactor/login.test.ts | 87 ------------------- test/unit/client/mocks/NotifierStub.ts | 33 +++++++ test/unit/client/mocks/jquery.ts | 24 ++++- .../client/secondfactor/TOTPValidator.test.ts | 10 +-- .../client/secondfactor/U2FValidator.test.ts | 30 ++++--- .../totp-register/totp-register.test.ts | 4 +- 39 files changed, 425 insertions(+), 245 deletions(-) create mode 100644 src/client/lib/INotifier.ts create mode 100644 src/client/lib/Notifier.ts rename src/client/{ => lib}/firstfactor/FirstFactorValidator.ts (62%) rename src/client/{ => lib}/firstfactor/UISelectors.ts (100%) rename src/client/{ => lib}/firstfactor/index.ts (73%) rename src/client/{ => lib}/reset-password/constants.ts (100%) rename src/client/{ => lib}/reset-password/reset-password-form.ts (69%) rename src/client/{ => lib}/reset-password/reset-password-request.ts (73%) rename src/client/{ => lib}/secondfactor/TOTPValidator.ts (91%) rename src/client/{ => lib}/secondfactor/U2FValidator.ts (75%) rename src/client/{ => lib}/secondfactor/constants.ts (100%) rename src/client/{ => lib}/secondfactor/index.ts (76%) rename src/client/{ => lib}/totp-register/totp-register.ts (100%) rename src/client/{ => lib}/totp-register/ui-selector.ts (100%) create mode 100644 src/client/lib/u2f-register/u2f-register.ts delete mode 100644 src/client/u2f-register/u2f-register.ts delete mode 100644 src/types/jquery-notify.d.ts create mode 100644 test/features/step_definitions/notifications.ts create mode 100644 test/unit/client/Notifier.test.ts delete mode 100644 test/unit/client/firstfactor/login.test.ts create mode 100644 test/unit/client/mocks/NotifierStub.ts diff --git a/Gruntfile.js b/Gruntfile.js index c5b590bb..e499db58 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -162,7 +162,7 @@ module.exports = function (grunt) { grunt.registerTask('docker-restart', ['run:docker-restart']); grunt.registerTask('unit-tests', ['run:unit-tests']); - grunt.registerTask('integration-tests', ['run:unit-tests']); + grunt.registerTask('integration-tests', ['run:integration-tests']); grunt.registerTask('test', ['unit-tests']); }; diff --git a/package.json b/package.json index 4036504a..60d72098 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,6 @@ "jsdom": "^11.0.0", "mocha": "^3.4.2", "mockdate": "^2.0.1", - "notifyjs-browser": "^0.4.2", "nyc": "^10.3.2", "power-assert": "^1.4.4", "proxyquire": "^1.8.0", diff --git a/src/client/css/01-main.css b/src/client/css/01-main.css index 269b3eb0..e4174f2c 100644 --- a/src/client/css/01-main.css +++ b/src/client/css/01-main.css @@ -19,4 +19,43 @@ body { .poweredby { font-size: 0.7em; color: #6b6b6b; +} + +/* notifications */ + +.notification { + padding: 10px; + border-radius: 6px; + display: none; +} + +.notification img { + width: 24px; + margin-right: 10px; +} + +.notification i, +.notification span { + display:table-cell; + vertical-align:middle; +} + +.info { + border: 1px solid #9cb1ff; + background-color: rgb(192, 220, 255); +} + +.success { + border: 1px solid #65ec7c; + background-color: rgb(163, 255, 157); +} + +.error { + border: 1px solid #ffa3a3; + background-color: rgb(255, 175, 175); +} + +.warning { + border: 1px solid #ffd743; + background-color: rgb(255, 230, 143); } \ No newline at end of file diff --git a/src/client/index.ts b/src/client/index.ts index 8d7e37ce..956edfc0 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -1,12 +1,12 @@ -import FirstFactorValidator = require("./firstfactor/FirstFactorValidator"); +import FirstFactorValidator = require("./lib/firstfactor/FirstFactorValidator"); -import FirstFactor from "./firstfactor/index"; -import SecondFactor from "./secondfactor/index"; -import TOTPRegister from "./totp-register/totp-register"; -import U2fRegister from "./u2f-register/u2f-register"; -import ResetPasswordRequest from "./reset-password/reset-password-request"; -import ResetPasswordForm from "./reset-password/reset-password-form"; +import FirstFactor from "./lib/firstfactor/index"; +import SecondFactor from "./lib/secondfactor/index"; +import TOTPRegister from "./lib/totp-register/totp-register"; +import U2fRegister from "./lib/u2f-register/u2f-register"; +import ResetPasswordRequest from "./lib/reset-password/reset-password-request"; +import ResetPasswordForm from "./lib/reset-password/reset-password-form"; import jslogger = require("js-logger"); import jQuery = require("jquery"); import u2fApi = require("u2f-api"); @@ -14,8 +14,6 @@ import u2fApi = require("u2f-api"); jslogger.useDefaults(); jslogger.setLevel(jslogger.INFO); -require("notifyjs-browser")(jQuery); - export = { firstfactor: function () { FirstFactor(window, jQuery, FirstFactorValidator, jslogger); diff --git a/src/client/lib/INotifier.ts b/src/client/lib/INotifier.ts new file mode 100644 index 00000000..df947538 --- /dev/null +++ b/src/client/lib/INotifier.ts @@ -0,0 +1,14 @@ + +declare type Handler = () => void; + +export interface Handlers { + onFadedIn: Handler; + onFadedOut: Handler; +} + +export interface INotifier { + success(msg: string, handlers?: Handlers): void; + error(msg: string, handlers?: Handlers): void; + warning(msg: string, handlers?: Handlers): void; + info(msg: string, handlers?: Handlers): void; +} \ No newline at end of file diff --git a/src/client/lib/Notifier.ts b/src/client/lib/Notifier.ts new file mode 100644 index 00000000..cc59ee88 --- /dev/null +++ b/src/client/lib/Notifier.ts @@ -0,0 +1,45 @@ + + +import util = require("util"); +import { INotifier, Handlers } from "./INotifier"; + +export class Notifier implements INotifier { + private element: JQuery; + + constructor(selector: string, $: JQueryStatic) { + this.element = $(selector); + } + + private displayAndFadeout(msg: string, statusType: string, handlers?: Handlers): void { + const that = this; + const FADE_TIME = 500; + const html = util.format('status %s\ + %s', statusType, statusType, msg); + this.element.html(html); + this.element.addClass(statusType); + this.element.fadeIn(FADE_TIME, function() { + handlers.onFadedIn(); + }) + .delay(4000) + .fadeOut(FADE_TIME, function() { + that.element.removeClass(statusType); + handlers.onFadedOut(); + }); + } + + success(msg: string, handlers?: Handlers) { + this.displayAndFadeout(msg, "success", handlers); + } + + error(msg: string, handlers?: Handlers) { + this.displayAndFadeout(msg, "error", handlers); + } + + warning(msg: string, handlers?: Handlers) { + this.displayAndFadeout(msg, "warning", handlers); + } + + info(msg: string, handlers?: Handlers) { + this.displayAndFadeout(msg, "info", handlers); + } +} \ No newline at end of file diff --git a/src/client/firstfactor/FirstFactorValidator.ts b/src/client/lib/firstfactor/FirstFactorValidator.ts similarity index 62% rename from src/client/firstfactor/FirstFactorValidator.ts rename to src/client/lib/firstfactor/FirstFactorValidator.ts index 07a27f7d..71ebc7ab 100644 --- a/src/client/firstfactor/FirstFactorValidator.ts +++ b/src/client/lib/firstfactor/FirstFactorValidator.ts @@ -1,8 +1,8 @@ import BluebirdPromise = require("bluebird"); -import Endpoints = require("../../server/endpoints"); +import Endpoints = require("../../../server/endpoints"); -export function validate(username: string, password: string, $: JQueryStatic): BluebirdPromise < void> { +export function validate(username: string, password: string, $: JQueryStatic): BluebirdPromise { return new BluebirdPromise(function (resolve, reject) { $.post(Endpoints.FIRST_FACTOR_POST, { username: username, @@ -12,9 +12,7 @@ export function validate(username: string, password: string, $: JQueryStatic): B resolve(); }) .fail(function (xhr: JQueryXHR, textStatus: string) { - if (xhr.status == 401) - reject(new Error("Authetication failed. Please check your credentials.")); - reject(new Error(textStatus)); + reject(new Error("Authetication failed. Please check your credentials.")); }); }); } diff --git a/src/client/firstfactor/UISelectors.ts b/src/client/lib/firstfactor/UISelectors.ts similarity index 100% rename from src/client/firstfactor/UISelectors.ts rename to src/client/lib/firstfactor/UISelectors.ts diff --git a/src/client/firstfactor/index.ts b/src/client/lib/firstfactor/index.ts similarity index 73% rename from src/client/firstfactor/index.ts rename to src/client/lib/firstfactor/index.ts index fea6b4e3..23b4a40f 100644 --- a/src/client/firstfactor/index.ts +++ b/src/client/lib/firstfactor/index.ts @@ -1,10 +1,15 @@ import FirstFactorValidator = require("./FirstFactorValidator"); import JSLogger = require("js-logger"); import UISelectors = require("./UISelectors"); +import { Notifier } from "../Notifier"; -import Endpoints = require("../../server/endpoints"); +import Endpoints = require("../../../server/endpoints"); + +export default function (window: Window, $: JQueryStatic, + firstFactorValidator: typeof FirstFactorValidator, jslogger: typeof JSLogger) { + + const notifier = new Notifier(".notification", $); -export default function (window: Window, $: JQueryStatic, firstFactorValidator: typeof FirstFactorValidator, jslogger: typeof JSLogger) { function onFormSubmitted() { const username: string = $(UISelectors.USERNAME_FIELD_ID).val(); const password: string = $(UISelectors.PASSWORD_FIELD_ID).val(); @@ -27,7 +32,7 @@ export default function (window: Window, $: JQueryStatic, firstFactorValidator: jslogger.debug("First factor failed."); $(UISelectors.PASSWORD_FIELD_ID).val(""); - $.notify("Error during authentication: " + err.message, "error"); + notifier.error("Authentication failed. Please double check your credentials."); } diff --git a/src/client/reset-password/constants.ts b/src/client/lib/reset-password/constants.ts similarity index 100% rename from src/client/reset-password/constants.ts rename to src/client/lib/reset-password/constants.ts diff --git a/src/client/reset-password/reset-password-form.ts b/src/client/lib/reset-password/reset-password-form.ts similarity index 69% rename from src/client/reset-password/reset-password-form.ts rename to src/client/lib/reset-password/reset-password-form.ts index dfd48e45..26ec4ec1 100644 --- a/src/client/reset-password/reset-password-form.ts +++ b/src/client/lib/reset-password/reset-password-form.ts @@ -1,9 +1,12 @@ import BluebirdPromise = require("bluebird"); -import Endpoints = require("../../server/endpoints"); +import Endpoints = require("../../../server/endpoints"); import Constants = require("./constants"); +import { Notifier } from "../Notifier"; export default function (window: Window, $: JQueryStatic) { + const notifier = new Notifier(".notification", $); + function modifyPassword(newPassword: string) { return new BluebirdPromise(function (resolve, reject) { $.post(Endpoints.RESET_PASSWORD_FORM_POST, { @@ -23,22 +26,22 @@ export default function (window: Window, $: JQueryStatic) { const password2 = $("#password2").val(); if (!password1 || !password2) { - $.notify("You must enter your new password twice.", "warn"); + notifier.warning("You must enter your new password twice."); return false; } if (password1 != password2) { - $.notify("The passwords are different", "warn"); + notifier.warning("The passwords are different."); return false; } modifyPassword(password1) .then(function () { - $.notify("Your password has been changed. Please login again", "success"); + notifier.success("Your password has been changed. Please log in again."); window.location.href = Endpoints.FIRST_FACTOR_GET; }) .error(function () { - $.notify("An error occurred during password change.", "warn"); + notifier.warning("An error occurred during password reset. Your password has not been changed."); }); return false; } diff --git a/src/client/reset-password/reset-password-request.ts b/src/client/lib/reset-password/reset-password-request.ts similarity index 73% rename from src/client/reset-password/reset-password-request.ts rename to src/client/lib/reset-password/reset-password-request.ts index 60630977..8ff450f4 100644 --- a/src/client/reset-password/reset-password-request.ts +++ b/src/client/lib/reset-password/reset-password-request.ts @@ -1,11 +1,14 @@ import BluebirdPromise = require("bluebird"); -import Endpoints = require("../../server/endpoints"); +import Endpoints = require("../../../server/endpoints"); import Constants = require("./constants"); import jslogger = require("js-logger"); +import { Notifier } from "../Notifier"; export default function(window: Window, $: JQueryStatic) { + const notifier = new Notifier(".notification", $); + function requestPasswordReset(username: string) { return new BluebirdPromise(function (resolve, reject) { $.get(Endpoints.RESET_PASSWORD_IDENTITY_START_GET, { @@ -24,19 +27,19 @@ export default function(window: Window, $: JQueryStatic) { const username = $("#username").val(); if (!username) { - $.notify("You must provide your username to reset your password.", "warn"); + notifier.warning("You must provide your username to reset your password."); return; } requestPasswordReset(username) .then(function () { - $.notify("An email has been sent. Click on the link to change your password.", "success"); + notifier.success("An email has been sent to you. Follow the link to change your password."); setTimeout(function () { window.location.replace(Endpoints.FIRST_FACTOR_GET); }, 1000); }) .error(function () { - $.notify("Are you sure this is your username?", "warn"); + notifier.warning("Are you sure this is your username?"); }); return false; } diff --git a/src/client/secondfactor/TOTPValidator.ts b/src/client/lib/secondfactor/TOTPValidator.ts similarity index 91% rename from src/client/secondfactor/TOTPValidator.ts rename to src/client/lib/secondfactor/TOTPValidator.ts index 7538f7f1..4b1d0ffb 100644 --- a/src/client/secondfactor/TOTPValidator.ts +++ b/src/client/lib/secondfactor/TOTPValidator.ts @@ -1,6 +1,6 @@ import BluebirdPromise = require("bluebird"); -import Endpoints = require("../../server/endpoints"); +import Endpoints = require("../../../server/endpoints"); export function validate(token: string, $: JQueryStatic): BluebirdPromise { return new BluebirdPromise(function (resolve, reject) { diff --git a/src/client/secondfactor/U2FValidator.ts b/src/client/lib/secondfactor/U2FValidator.ts similarity index 75% rename from src/client/secondfactor/U2FValidator.ts rename to src/client/lib/secondfactor/U2FValidator.ts index fb5da8e1..b1fdb595 100644 --- a/src/client/secondfactor/U2FValidator.ts +++ b/src/client/lib/secondfactor/U2FValidator.ts @@ -2,8 +2,9 @@ import U2fApi = require("u2f-api"); import U2f = require("u2f"); import BluebirdPromise = require("bluebird"); -import { SignMessage } from "../../server/lib/routes/secondfactor/u2f/sign_request/SignMessage"; -import Endpoints = require("../../server/endpoints"); +import { SignMessage } from "../../../server/lib/routes/secondfactor/u2f/sign_request/SignMessage"; +import Endpoints = require("../../../server/endpoints"); +import { INotifier } from "../INotifier"; function finishU2fAuthentication(responseData: U2fApi.SignResponse, $: JQueryStatic): BluebirdPromise { return new BluebirdPromise(function (resolve, reject) { @@ -22,11 +23,11 @@ function finishU2fAuthentication(responseData: U2fApi.SignResponse, $: JQuerySta }); } -function startU2fAuthentication($: JQueryStatic, u2fApi: typeof U2fApi): BluebirdPromise { +function startU2fAuthentication($: JQueryStatic, notifier: INotifier, u2fApi: typeof U2fApi): BluebirdPromise { return new BluebirdPromise(function (resolve, reject) { $.get(Endpoints.SECOND_FACTOR_U2F_SIGN_REQUEST_GET, {}, undefined, "json") .done(function (signResponse: SignMessage) { - $.notify("Please touch the token", "info"); + notifier.info("Please touch the token"); const signRequest: U2fApi.SignRequest = { appId: signResponse.request.appId, @@ -41,7 +42,7 @@ function startU2fAuthentication($: JQueryStatic, u2fApi: typeof U2fApi): Bluebir .then(function (data) { resolve(data); }, function (err) { - $.notify("Error when finish U2F transaction", "error"); + notifier.error("Error when finish U2F transaction"); reject(err); }); }) @@ -56,6 +57,6 @@ function startU2fAuthentication($: JQueryStatic, u2fApi: typeof U2fApi): Bluebir } -export function validate($: JQueryStatic, u2fApi: typeof U2fApi): BluebirdPromise { - return startU2fAuthentication($, u2fApi); +export function validate($: JQueryStatic, notifier: INotifier, u2fApi: typeof U2fApi): BluebirdPromise { + return startU2fAuthentication($, notifier, u2fApi); } diff --git a/src/client/secondfactor/constants.ts b/src/client/lib/secondfactor/constants.ts similarity index 100% rename from src/client/secondfactor/constants.ts rename to src/client/lib/secondfactor/constants.ts diff --git a/src/client/secondfactor/index.ts b/src/client/lib/secondfactor/index.ts similarity index 76% rename from src/client/secondfactor/index.ts rename to src/client/lib/secondfactor/index.ts index 1129bc2a..022c4a95 100644 --- a/src/client/secondfactor/index.ts +++ b/src/client/lib/secondfactor/index.ts @@ -4,24 +4,25 @@ import jslogger = require("js-logger"); import TOTPValidator = require("./TOTPValidator"); import U2FValidator = require("./U2FValidator"); - -import Endpoints = require("../../server/endpoints"); - +import Endpoints = require("../../../server/endpoints"); import Constants = require("./constants"); +import { Notifier } from "../Notifier"; export default function (window: Window, $: JQueryStatic, u2fApi: typeof U2fApi) { + const notifierTotp = new Notifier(".notification-totp", $); + const notifierU2f = new Notifier(".notification-u2f", $); + function onAuthenticationSuccess(data: any) { window.location.href = data.redirection_url; } - function onSecondFactorTotpSuccess(data: any) { onAuthenticationSuccess(data); } function onSecondFactorTotpFailure(err: Error) { - $.notify("Error while validating TOTP token. Cause: " + err.message, "error"); + notifierTotp.error("Problem with TOTP validation."); } function onU2fAuthenticationSuccess(data: any) { @@ -29,10 +30,9 @@ export default function (window: Window, $: JQueryStatic, u2fApi: typeof U2fApi) } function onU2fAuthenticationFailure() { - $.notify("Problem with U2F authentication. Did you register before authenticating?", "warn"); + notifierU2f.error("Problem with U2F validation. Did you register before authenticating?"); } - function onTOTPFormSubmitted(): boolean { const token = $(Constants.TOTP_TOKEN_SELECTOR).val(); jslogger.debug("TOTP token is %s", token); @@ -45,7 +45,7 @@ export default function (window: Window, $: JQueryStatic, u2fApi: typeof U2fApi) function onU2FFormSubmitted(): boolean { jslogger.debug("Start U2F authentication"); - U2FValidator.validate($, U2fApi) + U2FValidator.validate($, notifierU2f, U2fApi) .then(onU2fAuthenticationSuccess, onU2fAuthenticationFailure); return false; } diff --git a/src/client/totp-register/totp-register.ts b/src/client/lib/totp-register/totp-register.ts similarity index 100% rename from src/client/totp-register/totp-register.ts rename to src/client/lib/totp-register/totp-register.ts diff --git a/src/client/totp-register/ui-selector.ts b/src/client/lib/totp-register/ui-selector.ts similarity index 100% rename from src/client/totp-register/ui-selector.ts rename to src/client/lib/totp-register/ui-selector.ts diff --git a/src/client/lib/u2f-register/u2f-register.ts b/src/client/lib/u2f-register/u2f-register.ts new file mode 100644 index 00000000..e34706bc --- /dev/null +++ b/src/client/lib/u2f-register/u2f-register.ts @@ -0,0 +1,62 @@ + +import BluebirdPromise = require("bluebird"); +import U2f = require("u2f"); +import u2fApi = require("u2f-api"); +import Endpoints = require("../../../server/endpoints"); +import jslogger = require("js-logger"); +import { Notifier } from "../Notifier"; + +export default function (window: Window, $: JQueryStatic) { + const notifier = new Notifier(".notification", $); + + function checkRegistration(regResponse: u2fApi.RegisterResponse): BluebirdPromise { + const registrationData: U2f.RegistrationData = regResponse; + + jslogger.debug("registrationResponse = %s", JSON.stringify(registrationData)); + + return new BluebirdPromise(function (resolve, reject) { + $.post(Endpoints.SECOND_FACTOR_U2F_REGISTER_POST, registrationData, undefined, "json") + .done(function (data) { + resolve(data.redirection_url); + }) + .fail(function (xhr, status) { + reject(); + }); + }); + } + + function requestRegistration(): BluebirdPromise { + return new BluebirdPromise(function (resolve, reject) { + $.get(Endpoints.SECOND_FACTOR_U2F_REGISTER_REQUEST_GET, {}, undefined, "json") + .done(function (registrationRequest: U2f.Request) { + jslogger.debug("registrationRequest = %s", JSON.stringify(registrationRequest)); + + const registerRequest: u2fApi.RegisterRequest = registrationRequest; + u2fApi.register([registerRequest], [], 120) + .then(function (res: u2fApi.RegisterResponse) { + return checkRegistration(res); + }) + .then(function (redirectionUrl: string) { + resolve(redirectionUrl); + }) + .catch(function (err: Error) { + reject(err); + }); + }); + }); + } + + function onRegisterFailure(err: Error) { + notifier.error("Problem while registering your U2F device."); + } + + $(document).ready(function () { + requestRegistration() + .then(function (redirectionUrl: string) { + document.location.href = redirectionUrl; + }) + .error(function (err) { + onRegisterFailure(err); + }); + }); +} diff --git a/src/client/u2f-register/u2f-register.ts b/src/client/u2f-register/u2f-register.ts deleted file mode 100644 index d584ab03..00000000 --- a/src/client/u2f-register/u2f-register.ts +++ /dev/null @@ -1,53 +0,0 @@ - -import BluebirdPromise = require("bluebird"); -import U2f = require("u2f"); -import u2fApi = require("u2f-api"); - -import Endpoints = require("../../server/endpoints"); -import jslogger = require("js-logger"); - -export default function(window: Window, $: JQueryStatic) { - - function checkRegistration(regResponse: u2fApi.RegisterResponse, fn: (err: Error) => void) { - const registrationData: U2f.RegistrationData = regResponse; - - jslogger.debug("registrationResponse = %s", JSON.stringify(registrationData)); - - $.post(Endpoints.SECOND_FACTOR_U2F_REGISTER_POST, registrationData, undefined, "json") - .done(function (data) { - document.location.href = data.redirection_url; - }) - .fail(function (xhr, status) { - $.notify("Error when finish U2F transaction" + status); - }); - } - - function requestRegistration(fn: (err: Error) => void) { - $.get(Endpoints.SECOND_FACTOR_U2F_REGISTER_REQUEST_GET, {}, undefined, "json") - .done(function (registrationRequest: U2f.Request) { - jslogger.debug("registrationRequest = %s", JSON.stringify(registrationRequest)); - - const registerRequest: u2fApi.RegisterRequest = registrationRequest; - u2fApi.register([registerRequest], [], 120) - .then(function (res: u2fApi.RegisterResponse) { - checkRegistration(res, fn); - }) - .catch(function (err: Error) { - fn(err); - }); - }); - } - - function onRegisterFailure(err: Error) { - $.notify("Problem authenticating with U2F.", "error"); - } - - $(document).ready(function () { - requestRegistration(function (err: Error) { - if (err) { - onRegisterFailure(err); - return; - } - }); - }); -} diff --git a/src/server/views/firstfactor.pug b/src/server/views/firstfactor.pug index ee8ed48a..4c93b576 100644 --- a/src/server/views/firstfactor.pug +++ b/src/server/views/firstfactor.pug @@ -5,6 +5,7 @@ block form-header block content +