Added U2F Support for YubiKey

This commit is contained in:
Fabian Stamm
2019-03-12 21:06:09 -04:00
parent aa47e6c92f
commit c54406564c
41 changed files with 2955 additions and 2005 deletions

View File

@ -1,7 +1,9 @@
import { Request, Response, NextFunction, RequestHandler } from "express";
import promiseMiddleware from "../../helper/promiseMiddleware";
function call(handler: RequestHandler, req: Request, res: Response) {
type RH = (req: Request, res: Response, next?: NextFunction) => any;
function call(handler: RH, req: Request, res: Response) {
return new Promise((yes, no) => {
let p = handler(req, res, (err) => {
if (err) no(err);
@ -11,7 +13,7 @@ function call(handler: RequestHandler, req: Request, res: Response) {
})
}
const Stacker = (...handler: RequestHandler[]) => {
const Stacker = (...handler: RH[]) => {
return promiseMiddleware(async (req: Request, res: Response, next: NextFunction) => {
let hc = handler.concat();
while (hc.length > 0) {

View File

@ -1,5 +1,5 @@
import { NextFunction, Request, Response } from "express";
import LoginToken from "../../models/login_token";
import LoginToken, { CheckToken } from "../../models/login_token";
import Logging from "@hibas123/nodelogging";
import RequestError, { HttpStatusCode } from "../../helper/request_error";
import User from "../../models/user";
@ -14,7 +14,7 @@ class Invalid extends Error { }
* @param json Checks if requests wants an json or html for returning errors
* @param redirect_uri Sets the uri to redirect, if json is not set and user not logged in
*/
export function GetUserMiddleware(json = false, special_token: boolean = false, redirect_uri?: string) {
export function GetUserMiddleware(json = false, special_required: boolean = false, redirect_uri?: string, validated = true) {
return promiseMiddleware(async function (req: Request, res: Response, next?: NextFunction) {
const invalid = () => {
throw new Invalid();
@ -24,8 +24,7 @@ export function GetUserMiddleware(json = false, special_token: boolean = false,
if (!login) invalid()
let token = await LoginToken.findOne({ token: login, valid: true })
if (!token) invalid()
if (!token.validated) invalid();
if (!await CheckToken(token, validated)) invalid();
let user = await User.findById(token.user);
if (!user) {
@ -34,31 +33,23 @@ export function GetUserMiddleware(json = false, special_token: boolean = false,
invalid();
}
if (token.validTill.getTime() < new Date().getTime()) { //Token expired
token.valid = false;
await LoginToken.save(token);
invalid()
}
let special_token;
if (special) {
Logging.debug("Special found")
let st = await LoginToken.findOne({ token: special, special: true, valid: true })
if (st && st.validated && st.valid && st.user.toHexString() === token.user.toHexString()) {
if (st.validTill.getTime() < new Date().getTime()) { //Token expired
Logging.debug("Special expired")
st.valid = false;
await LoginToken.save(st);
} else {
Logging.debug("Special valid")
req.special = true;
}
}
special_token = await LoginToken.findOne({ token: special, special: true, valid: true, user: token.user })
if (!await CheckToken(special_token, validated))
invalid();
req.special = true;
}
if (special_token && !req.special) invalid();
if (special_required && !req.special) invalid();
req.user = user
req.isAdmin = user.admin;
req.token = {
login: token,
special: special_token
}
if (next)
next()
@ -67,7 +58,7 @@ export function GetUserMiddleware(json = false, special_token: boolean = false,
if (e instanceof Invalid) {
if (req.method === "GET" && !json) {
res.status(HttpStatusCode.UNAUTHORIZED)
res.redirect("/login?base64=true&state=" + new Buffer(redirect_uri ? redirect_uri : req.originalUrl).toString("base64"))
res.redirect("/login?base64=true&state=" + Buffer.from(redirect_uri ? redirect_uri : req.originalUrl).toString("base64"))
} else {
throw new RequestError(req.__("You are not logged in or your login is expired"), HttpStatusCode.UNAUTHORIZED)
}