import * as crypto from "crypto"; import { Knex } from "knex"; import { promisify } from "util"; const pbkdf2 = promisify(crypto.pbkdf2); type Account = { username: string; hashed_password: any; salt: any; }; export class Authenticator { tableName = "tokens"; constructor(private db: Knex) {} middleware(req: any, res: any, next: any) { console.log("GOing through here", req.headers.authorization); // if (req.headers) next(); } async ensureTables() { if (!(await this.db.schema.hasTable(this.tableName))) { await this.db.schema.createTable(this.tableName, (table) => { table.string("username"); table.binary("hashed_password"); table.binary("salt"); table.primary(["username"]); }); // await this.createAccount("admin", "admin"); console.log(`Created table ${this.tableName}`); } } async createAccount(username: string, password: string) { var salt = crypto.randomBytes(16); let encryptedPassword = await pbkdf2(password, salt, 310000, 32, "sha256"); await this.db(this.tableName).insert({ username, hashed_password: encryptedPassword, salt, }); } async updatePassword(username: string, password: string) { var salt = crypto.randomBytes(16); let encryptedPassword = await pbkdf2(password, salt, 310000, 32, "sha256"); await this.db(this.tableName).update({ username, hashed_password: encryptedPassword, salt, }); } async verify(username: string, password: string): Promise { let users = await this.db(this.tableName).where({ username }); if (users.length === 0) { throw new Error(`No such user: ${username}`); } let user = users[0]; let encryptedPassword = await pbkdf2( password, user.salt, 310000, 32, "sha256" ); return crypto.timingSafeEqual(user.hashed_password, encryptedPassword); } }