blockstack-auth
Version:
Blockstack Auth Library
139 lines (114 loc) • 5.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.verifyAuthInProfile = verifyAuthInProfile;
exports.verifyKeychainChild = verifyKeychainChild;
exports.verifyAuthMessage = verifyAuthMessage;
var _jsontokens = require('jsontokens');
var _keyEncoder = require('key-encoder');
var _hasprop = require('hasprop');
var _hasprop2 = _interopRequireDefault(_hasprop);
var _promise = require('promise');
var _promise2 = _interopRequireDefault(_promise);
var _keychainManager = require('keychain-manager');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function verifyAuthInProfile(blockstackResolver, username, key, isKeychain, resolve, reject) {
/* Verifies the auth field in a user profile */
blockstackResolver([username], function (data) {
if (data === null || data === '') {
resolve(false);
}
if (data.hasOwnProperty(username)) {
var item = data[username];
if ((0, _hasprop2.default)(item, 'profile.auth')) {
var authInfo = data[username].profile.auth;
if (Object.prototype.toString.call(authInfo) === '[object Array]') {
authInfo.forEach(function (authItem) {
if (isKeychain) {
if ((0, _hasprop2.default)(authItem, 'publicKeychain')) {
if (key === authItem.publicKeychain) {
resolve(true);
return;
}
}
} else {
if ((0, _hasprop2.default)(authItem, 'publicKey')) {
if (key === authItem.publicKey) {
resolve(true);
return;
}
}
}
});
}
}
}
resolve(false);
}, function (err) {
reject(err);
});
}
function verifyKeychainChild(publicKeychainString, childPublicKey, chainPath, resolve, reject) {
var publicKeychain = new _keychainManager.PublicKeychain(publicKeychainString);
var derivedChildPublicKey = publicKeychain.descendant(chainPath).publicKey().toString();
resolve(derivedChildPublicKey === childPublicKey);
}
function verifyAuthMessage(token, blockstackResolver, resolve, reject) {
var decodedToken = (0, _jsontokens.decodeToken)(token),
payload = decodedToken.payload;
if (!(0, _hasprop2.default)(payload, 'issuer.publicKey')) {
reject('token must have a public key');
}
var hasKeychain = void 0,
publicKey = payload.issuer.publicKey;
var tokenVerifier = new _jsontokens.TokenVerifier('ES256k', publicKey),
tokenSignerVerified = tokenVerifier.verify(token);
if (!tokenSignerVerified) {
resolve(tokenSignerVerified);
return;
}
if (!(0, _hasprop2.default)(payload, 'issuer.username') && !(0, _hasprop2.default)(payload, 'issuer.publicKeychain') && !(0, _hasprop2.default)(payload, 'issuer.chainPath')) {
// Issuer only contains the public key
resolve(tokenSignerVerified);
return;
} else if ((0, _hasprop2.default)(payload, 'issuer.username') && !(0, _hasprop2.default)(payload, 'issuer.publicKeychain') && !(0, _hasprop2.default)(payload, 'issuer.chainPath')) {
// Issuer only contains the blockchain ID and signing public key
hasKeychain = false;
} else if ((0, _hasprop2.default)(payload, 'issuer.username') && (0, _hasprop2.default)(payload, 'issuer.publicKeychain') && (0, _hasprop2.default)(payload, 'issuer.chainPath')) {
// Issuer contains the blockchain ID, public keychain, chain path,
// and signing public key
hasKeychain = true;
} else {
// Issuer is invalid
reject('token must have a username, and may have a publicKeychain and chainPath');
}
var username = payload.issuer.username;
if (!hasKeychain) {
var verifyAuthInProfilePromise = new _promise2.default(function (resolve, reject) {
verifyAuthInProfile(blockstackResolver, username, publicKey, false, resolve, reject);
});
verifyAuthInProfilePromise.then(function (value) {
resolve(value);
});
} else {
(function () {
var publicKeychain = payload.issuer.publicKeychain,
childPublicKey = payload.issuer.publicKey,
chainPath = payload.issuer.chainPath;
var verifyKeychainChildPromise = new _promise2.default(function (resolve, reject) {
verifyKeychainChild(publicKeychain, childPublicKey, chainPath, resolve, reject);
});
var verifyAuthInProfilePromise = new _promise2.default(function (resolve, reject) {
verifyAuthInProfile(blockstackResolver, username, publicKeychain, true, resolve, reject);
});
_promise2.default.all([verifyKeychainChildPromise, verifyAuthInProfilePromise]).then(function (results) {
var keychainChildIsValid = results[0],
authInProfileIsValid = results[1];
resolve(keychainChildIsValid && authInProfileIsValid);
}, function (err) {
reject(err);
});
})();
}
}