UNPKG

@perfood/couch-auth

Version:

Easy and secure authentication for CouchDB/Cloudant. Based on SuperLogin, updated and rewritten in Typescript.

96 lines (95 loc) 3.13 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Hashing = exports.hashCouchPassword = void 0; const couch_pwd_1 = __importDefault(require("@sl-nx/couch-pwd")); const util_1 = require("./util"); const pwd = new couch_pwd_1.default(); function hashCouchPassword(password) { return new Promise(function (resolve, reject) { pwd.hash(password, function (err, salt, hash) { if (err) { return reject(err); } return resolve({ salt: salt, derived_key: hash }); }); }); } exports.hashCouchPassword = hashCouchPassword; class Hashing { constructor(config) { this.hashers = []; this.times = []; this.dummyHashObject = { iterations: 10 }; const iterationPairs = config.security?.iterations; if (iterationPairs) { for (const pair of config.security.iterations) { this.times.push(pair[0]); this.hashers.push(new couch_pwd_1.default(pair[1])); } } this.hashUserPassword((0, util_1.URLSafeUUID)()).then(dummy => { this.dummyHashObject = dummy; }); } getHasherForTimestamp(ts = undefined) { let ret = pwd; if (this.times.length === 0 || ts === undefined) { return ret; } for (let idx = 0; idx < this.times.length; idx++) { if (ts > this.times[idx]) { ret = this.hashers[idx]; } else { break; } } return ret; } hashUserPassword(pw) { const t = new Date().valueOf(); return new Promise((resolve, reject) => { this.getHasherForTimestamp(t).hash(pw, (err, salt, hash) => { if (err) { return reject(err); } return resolve({ salt: salt, derived_key: hash }); }); }).then((hr) => { hr.created = t; return hr; }); } verifyUserPassword(hashObj, pw) { const salt = hashObj.salt ?? this.dummyHashObject.salt; const derived_key = hashObj.derived_key ?? this.dummyHashObject.derived_key; let created = hashObj.created; if (!hashObj.salt && !hashObj.derived_key) { created = this.dummyHashObject.created; } return new Promise((resolve, reject) => { const hasher = this.getHasherForTimestamp(created); hasher.hash(pw, salt, (err, hash) => { if (err) { return reject(err); } else if (hash !== derived_key) { return reject(false); } else { return resolve(true); } }); }); } } exports.Hashing = Hashing;