@perfood/couch-auth
Version:
Easy and secure authentication for CouchDB/Cloudant. Based on SuperLogin, updated and rewritten in Typescript.
85 lines (84 loc) • 2.77 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Hashing = void 0;
const couch_pwd_1 = __importDefault(require("@sl-nx/couch-pwd"));
const util_1 = require("./util");
const pwd = new couch_pwd_1.default();
/**
* Class for hashing and verifying sl-user passwords
*/
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;