cleaning up old code

This commit is contained in:
Timo Hocker 2020-03-06 18:02:08 +01:00
parent dba931ee48
commit 0f7bc13d3f
6 changed files with 5020 additions and 19 deletions

185
index.js
View File

@ -0,0 +1,185 @@
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* Created by Timo Hocker <timo@scode.ovh>, January 2020
*/
// @ts-nocheck
/* eslint-disable no-magic-numbers */
'use strict';
const password_helper = require ('@scode/password-helper');
const crypto = require ('@scode/crypto-helper');
const consts = require ('@scode/consts');
const me = {};
/**
* initializes the module
*
* @param {Array<RegExp>} ignore_paths array of regex to skip auth
* @param {Function<Promise|object>} get_user
* function that returns {id:number, password:string, salt:string}
* for a given user identifier
*/
function init (ignore_paths, get_user) {
me.get_user = get_user;
me.session_timeout_milliseconds = 300000;
me.ignore_paths = ignore_paths;
me.jwt_secret = crypto.create_salt ();
me.app_id = crypto.create_salt ();
}
/**
* tries to authenticate a user
*
* @param {string} user name or email of the given user
* @param {string} password hashed password
* @returns {Promise<string>} session key if successful
*/
async function authenticate (user, password) {
const user_entry
= await new Promise ((res) => res (me.get_user (user)));
if (!user_entry)
return null;
if (!await password_helper.verify (user_entry.password, password))
return null;
const session_key = crypto.sign_object (
{ id: user_entry.id },
me.jwt_secret
);
return session_key;
}
/**
* gets the correct salt for a given user
*
* @param {string} user user name or email to query
*/
async function salt (user) {
const user_entry
= await new Promise ((res) => res (me.get_user (user)));
if (!user_entry)
return null;
return user_entry.salt;
}
/**
* block if no auth header found
*
* @param {string} session session key
* @param {string} user user name
* @param {any} res response object
* @returns {boolean} true if handler blocked request
*/
function request_handler_block (session, user, res) {
if (typeof session === 'undefined' && typeof user === 'undefined') {
res.status (consts.http.status_unauthorized);
res.end ();
return true;
}
return false;
}
/**
* handle authentication
*
* @param {string} session session key
* @param {string} user user name
* @param {string} key user hash
* @param {any} res response object
* @param {any} next next handler
* @returns {Promise<boolean>} true if handler authenticated
*/
async function request_handler_authenticate (session, user, key, res, next) {
if (typeof session === 'undefined' && typeof user !== 'undefined') {
if (typeof key === 'undefined') {
const user_salt = await salt (user);
res.status (
user_salt === null
? consts.http.status_forbidden
: consts.http.status_ok
);
res.end (user_salt);
return true;
}
const session_key = await authenticate (user, key);
res.status (
session_key === null
? consts.http.status_forbidden
: consts.http.status_ok
)
.cookie (me.app_id, session_key, { maxAge: 900000, httpOnly: true })
.end (session_key);
return true;
}
try {
const jwt = crypto.verify_signature (
session,
me.jwt_secret,
me.session_timeout_milliseconds
);
res.locals.user_id = jwt.id;
const new_user_token = crypto.sign_object (
{ id: jwt.id },
me.jwt_secret
);
res.cookie (
me.app_id,
new_user_token,
{ maxAge: 900000, httpOnly: true }
)
.header ('session', new_user_token);
next ();
return true;
}
catch (err) {
return false;
}
}
/**
* handles http requests
*
* @param {any} req request
* @param {any} res response
* @param {any} next next handler
*/
async function request_handler (req, res, next) {
if (Array.isArray (me.ignore_paths)) {
for (const regex of me.ignore_paths) {
if (regex.test (req.url)) {
next ();
return;
}
}
}
const { user, key, session: header_session } = req.headers;
const cookie_session = typeof req.cookies === 'undefined'
? null
: req.cookies[me.app_id];
const session = cookie_session || header_session;
if (request_handler_block (session, user, res))
return;
if (await request_handler_authenticate (session, user, key, res, next))
return;
res.status (consts.http.status_forbidden);
res.end ();
}
module.exports = (get_user, ignore_paths = []) => {
init (ignore_paths, get_user);
return request_handler;
};

View File

@ -7,6 +7,8 @@ const cookie_parser = require ('cookie-parser');
const auth = require ('./index');
const knex = require ('knex');
const path = require ('path');
const consts = require ('@scode/consts');
const crypto = require ('@scode/crypto-helper');
const fs = require ('fs-extra');
@ -48,7 +50,7 @@ async function start_server () {
app.use (authentication.handler);
app.get ('/', (req, res) => {
res.status (http_consts.status_ok)
res.status (consts.http_consts.status_ok)
.end ('foo');
});

View File

@ -5,14 +5,24 @@
"author": "Timo Hocker <t-hocker@web.de>",
"license": "MIT",
"devDependencies": {
"@scode/auth-client-helper": "^1.0.4",
"@scode/crypto-helper": "^1.1.9",
"@scode/eslint-config": "^1.2.26",
"ava": "^3.5.0",
"cookie-parser": "^1.4.4",
"eslint": "^6.8.0",
"express": "^4.17.1",
"fs-extra": "^8.1.0",
"knex": "^0.20.11",
"nyc": "^15.0.0"
},
"scripts": {
"lint": "eslint .",
"test": "nyc ava",
"ci": "yarn && node jenkins.js"
},
"dependencies": {
"@scode/consts": "^1.0.2",
"@scode/password-helper": "^1.0.3"
}
}

15
test/index.js Normal file
View File

@ -0,0 +1,15 @@
/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of auth-server-helper which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, March 2020
*/
// @ts-nocheck
'use strict';
const test = require ('ava');
test ('', () => {
});

3210
yarn-error.log Normal file

File diff suppressed because it is too large Load Diff

1615
yarn.lock

File diff suppressed because it is too large Load Diff