mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-07-25 08:09:41 +02:00
Password from env variable (#170)
* rm: remove the generate password file * rm: commander package * rm: remove the password reading from db * feat: password hash reading from env added * passHash replace with password * raw password comparison added * rm: user model and controller removed * update: auth route and token verification * replace multiple dotenv config with one * .env.sample added with updated docker yml * rm:remove the bcrypt * readme updated with .env * remove generatePassword from package json * updated docs * removed the console.log
This commit is contained in:
parent
aaf2644ed4
commit
303d670c49
13 changed files with 53 additions and 359 deletions
|
@ -5,8 +5,10 @@ import morgan from 'morgan';
|
|||
import rcParser from './utils/rcparser';
|
||||
import routes from './routes';
|
||||
import HttpException from './exceptions/httpException';
|
||||
import * as dotenv from 'dotenv';
|
||||
import config from 'config';
|
||||
|
||||
dotenv.config();
|
||||
const app = express();
|
||||
const localConfig = rcParser.getConfiguration();
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ class Transport {
|
|||
fs.writeFileSync(`${config.get('uploads')}/${filename}.${ext}`, buffer);
|
||||
|
||||
const fetchedContentType: string | null = fetchedFile.headers.get('content-type');
|
||||
let fetchedMimeType: string|undefined;
|
||||
let fetchedMimeType: string | undefined;
|
||||
|
||||
if (fetchedContentType === null) {
|
||||
fetchedMimeType = undefined;
|
||||
|
@ -96,8 +96,6 @@ class Transport {
|
|||
|
||||
let response = file.data;
|
||||
|
||||
console.log(response)
|
||||
|
||||
if (map) {
|
||||
response = Transport.composeResponse(file, map);
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
import User from '../models/user';
|
||||
|
||||
/**
|
||||
* @class Users
|
||||
* @classdesc Users controller
|
||||
*/
|
||||
class Users {
|
||||
/**
|
||||
* Find and return user model.
|
||||
*
|
||||
* @returns {Promise<User>}
|
||||
*/
|
||||
public static async get(): Promise<User> {
|
||||
const userData: User = await User.get();
|
||||
|
||||
return userData;
|
||||
}
|
||||
}
|
||||
|
||||
export default Users;
|
|
@ -1,40 +0,0 @@
|
|||
import database from '../utils/database/index';
|
||||
|
||||
const db = database['password'];
|
||||
|
||||
export interface UserData {
|
||||
passHash?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class User
|
||||
* @class User model
|
||||
*
|
||||
* @property {string} passHash - hashed password
|
||||
*/
|
||||
class User {
|
||||
public passHash?: string;
|
||||
|
||||
/**
|
||||
* @class
|
||||
*
|
||||
* @param {UserData} userData - user data for construct new object
|
||||
*/
|
||||
constructor(userData: UserData) {
|
||||
this.passHash = userData.passHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return model of user.
|
||||
* User is only one.
|
||||
*
|
||||
* @returns {Promise<User>}
|
||||
*/
|
||||
public static async get(): Promise<User> {
|
||||
const userData: UserData = await db.findOne({});
|
||||
|
||||
return new User(userData);
|
||||
}
|
||||
}
|
||||
|
||||
export default User;
|
|
@ -1,12 +1,7 @@
|
|||
import express, { Request, Response } from 'express';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import config from 'config';
|
||||
import bcrypt from 'bcrypt';
|
||||
import csrf from 'csurf';
|
||||
import * as dotenv from 'dotenv';
|
||||
import Users from '../controllers/users';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const router = express.Router();
|
||||
const csrfProtection = csrf({ cookie: true });
|
||||
|
@ -27,10 +22,7 @@ router.get('/auth', csrfProtection, function (req: Request, res: Response) {
|
|||
*/
|
||||
router.post('/auth', parseForm, csrfProtection, async (req: Request, res: Response) => {
|
||||
try {
|
||||
const userDoc = await Users.get();
|
||||
const passHash = userDoc.passHash;
|
||||
|
||||
if (!passHash) {
|
||||
if (!process.env.PASSWORD) {
|
||||
res.render('auth', {
|
||||
title: 'Login page',
|
||||
header: 'Password not set',
|
||||
|
@ -40,30 +32,28 @@ router.post('/auth', parseForm, csrfProtection, async (req: Request, res: Respon
|
|||
return;
|
||||
}
|
||||
|
||||
bcrypt.compare(req.body.password, passHash, async (err, result) => {
|
||||
if (err || result === false) {
|
||||
res.render('auth', {
|
||||
title: 'Login page',
|
||||
header: 'Wrong password',
|
||||
csrfToken: req.csrfToken(),
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const token = jwt.sign({
|
||||
iss: 'Codex Team',
|
||||
sub: 'auth',
|
||||
iat: Date.now(),
|
||||
}, passHash + config.get('secret'));
|
||||
|
||||
res.cookie('authToken', token, {
|
||||
httpOnly: true,
|
||||
expires: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1 year
|
||||
if (req.body.password !== process.env.PASSWORD) {
|
||||
res.render('auth', {
|
||||
title: 'Login page',
|
||||
header: 'Wrong password',
|
||||
csrfToken: req.csrfToken(),
|
||||
});
|
||||
|
||||
res.redirect('/');
|
||||
return;
|
||||
}
|
||||
|
||||
const token = jwt.sign({
|
||||
iss: 'Codex Team',
|
||||
sub: 'auth',
|
||||
iat: Date.now(),
|
||||
}, process.env.PASSWORD + config.get('secret'));
|
||||
|
||||
res.cookie('authToken', token, {
|
||||
httpOnly: true,
|
||||
expires: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1 year
|
||||
});
|
||||
|
||||
res.redirect('/');
|
||||
} catch (err) {
|
||||
res.render('auth', {
|
||||
title: 'Login page',
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import * as dotenv from 'dotenv';
|
||||
import config from 'config';
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import Users from '../../controllers/users';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
/**
|
||||
* Middleware for checking jwt token
|
||||
|
@ -17,16 +14,14 @@ export default async function verifyToken(req: Request, res: Response, next: Nex
|
|||
const token = req.cookies.authToken;
|
||||
|
||||
try {
|
||||
const userDoc = await Users.get();
|
||||
|
||||
if (!userDoc.passHash) {
|
||||
if (!process.env.PASSWORD) {
|
||||
res.locals.isAuthorized = false;
|
||||
next();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const decodedToken = jwt.verify(token, userDoc.passHash + config.get('secret'));
|
||||
const decodedToken = jwt.verify(token, process.env.PASSWORD + config.get('secret'));
|
||||
|
||||
res.locals.isAuthorized = !!decodedToken;
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ import { AliasData } from '../../models/alias';
|
|||
import { FileData } from '../../models/file';
|
||||
import { PageData } from '../../models/page';
|
||||
import { PageOrderData } from '../../models/pageOrder';
|
||||
import { UserData } from '../../models/user';
|
||||
import initDb from './initDb';
|
||||
|
||||
/**
|
||||
|
@ -170,7 +169,6 @@ export class Database<DocType> {
|
|||
|
||||
export default {
|
||||
pages: new Database<PageData>(initDb('pages')),
|
||||
password: new Database<UserData>(initDb('password')),
|
||||
aliases: new Database<AliasData>(initDb('aliases')),
|
||||
pagesOrder: new Database<PageOrderData>(initDb('pagesOrder')),
|
||||
files: new Database<FileData>(initDb('files')),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue