1
0
Fork 0
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:
Umang G. Patel 2022-04-24 16:54:36 +05:30 committed by GitHub
parent aaf2644ed4
commit 303d670c49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 53 additions and 359 deletions

View file

@ -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();

View file

@ -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);
}

View file

@ -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;

View file

@ -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;

View file

@ -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',

View file

@ -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;

View file

@ -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')),