blockstack
Version:
The Blockstack Javascript library for identity and authentication.
1,637 lines (1,381 loc) • 1.29 MB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.blockstack = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isUserSignedIn = isUserSignedIn;
exports.redirectUserToSignIn = redirectUserToSignIn;
exports.getAuthResponseToken = getAuthResponseToken;
exports.isSignInPending = isSignInPending;
exports.signUserIn = signUserIn;
exports.loadUserData = loadUserData;
exports.signUserOut = signUserOut;
exports.getAuthRequestFromURL = getAuthRequestFromURL;
exports.fetchAppManifest = fetchAppManifest;
exports.redirectUserToApp = redirectUserToApp;
var _queryString = require('query-string');
var _queryString2 = _interopRequireDefault(_queryString);
var _jsontokens = require('jsontokens');
var _authMessages = require('./authMessages');
var _index = require('../index');
var _customProtocolDetection = require('custom-protocol-detection');
var _customProtocolDetection2 = _interopRequireDefault(_customProtocolDetection);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var BLOCKSTACK_HANDLER = "blockstack";
var BLOCKSTACK_STORAGE_LABEL = "blockstack";
var DEFAULT_BLOCKSTACK_HOST = "https://blockstack.org/auth";
/**
* For applications
*/
function isUserSignedIn() {
return window.localStorage.getItem(BLOCKSTACK_STORAGE_LABEL) ? true : false;
}
function redirectUserToSignIn(authRequest) {
var blockstackIDHost = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_BLOCKSTACK_HOST;
var protocolURI = BLOCKSTACK_HANDLER + ":" + authRequest;
var httpsURI = blockstackIDHost + "?authRequest=" + authRequest;
(0, _customProtocolDetection2.default)(protocolURI, function () {
console.log('protocol handler not detected');
window.location = httpsURI;
}, function () {
console.log('protocol handler detected');
});
}
function getAuthResponseToken() {
var queryDict = _queryString2.default.parse(location.search);
return queryDict.authResponse ? queryDict.authResponse : null;
}
function isSignInPending() {
return getAuthResponseToken() ? true : false;
}
function signUserIn(callbackFunction) {
var authResponseToken = getAuthResponseToken();
if ((0, _authMessages.verifyAuthResponse)(authResponseToken)) {
var tokenPayload = (0, _jsontokens.decodeToken)(authResponseToken).payload;
var userData = {
username: tokenPayload.username,
profile: tokenPayload.profile,
authResponseToken: authResponseToken
};
window.localStorage.setItem(BLOCKSTACK_STORAGE_LABEL, JSON.stringify(userData));
callbackFunction(true);
} else {
callbackFunction(false);
}
}
function loadUserData(callbackFunction) {
var userData = JSON.parse(window.localStorage.getItem(BLOCKSTACK_STORAGE_LABEL));
callbackFunction(userData);
}
function signUserOut(redirectURL) {
window.localStorage.removeItem(BLOCKSTACK_STORAGE_LABEL);
window.location = redirectURL;
}
/**
* For identity providers
*/
function getAuthRequestFromURL() {
var queryDict = _queryString2.default.parse(location.search);
if (queryDict.authRequest !== null && queryDict.authRequest !== undefined) {
return queryDict.authRequest.split(BLOCKSTACK_HANDLER + ':').join('');
} else {
return null;
}
}
function fetchAppManifest(authRequest) {
return new Promise(function (resolve, reject) {
if (!authRequest) {
reject("Invalid auth request");
} else {
var payload = (0, _jsontokens.decodeToken)(authRequest).payload;
var manifestURI = payload.manifest_uri;
try {
fetch(manifestURI).then(function (response) {
return response.text();
}).then(function (responseText) {
return JSON.parse(responseText);
}).then(function (responseJSON) {
resolve(responseJSON);
}).catch(function (e) {
console.log(e.stack);
reject("URI request couldn't be completed");
});
} catch (e) {
console.log(e.stack);
reject("URI request couldn't be completed");
}
}
});
}
function redirectUserToApp(authRequest, authResponse) {
var payload = (0, _jsontokens.decodeToken)(authRequest).payload;
var redirectURI = payload.redirect_uri;
if (redirectURI) {
redirectURI = (0, _index.updateQueryStringParameter)(redirectURI, 'authResponse', authResponse);
} else {
throw new Error("Invalid redirect URI");
}
window.location = redirectURI;
}
},{"../index":5,"./authMessages":2,"custom-protocol-detection":114,"jsontokens":166,"query-string":223}],2:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.makeAuthRequest = makeAuthRequest;
exports.makeAuthResponse = makeAuthResponse;
exports.doSignaturesMatchPublicKeys = doSignaturesMatchPublicKeys;
exports.doPublicKeysMatchIssuer = doPublicKeysMatchIssuer;
exports.doPublicKeysMatchUsername = doPublicKeysMatchUsername;
exports.isIssuanceDateValid = isIssuanceDateValid;
exports.isExpirationDateValid = isExpirationDateValid;
exports.verifyAuthRequest = verifyAuthRequest;
exports.verifyAuthResponse = verifyAuthResponse;
var _jsontokens = require('jsontokens');
var _index = require('../index');
require('isomorphic-fetch');
function makeAuthRequest(privateKey, domain_name) {
var manifestURI = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var redirectURI = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var scopes = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
var expiresAt = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : (0, _index.nextHour)().getTime();
var token = null;
if (domain_name === null) {
throw new Error("Invalid app domain name");
}
if (manifestURI === null) {
manifestURI = domain_name + '/manifest.json';
}
if (redirectURI === null) {
redirectURI = domain_name;
}
/* Create the payload */
var payload = {
jti: (0, _index.makeUUID4)(),
iat: Math.floor(new Date().getTime() / 1000), // JWT times are in seconds
exp: Math.floor(expiresAt / 1000), // JWT times are in seconds
iss: null,
public_keys: [],
domain_name: domain_name,
manifest_uri: manifestURI,
redirect_uri: redirectURI,
scopes: scopes
};
if (privateKey === null) {
/* Create an unsecured token and return it */
token = (0, _jsontokens.createUnsecuredToken)(payload);
} else {
/* Convert the private key to a public key to an issuer */
var publicKey = _jsontokens.SECP256K1Client.derivePublicKey(privateKey);
payload.public_keys = [publicKey];
var address = (0, _index.publicKeyToAddress)(publicKey);
payload.iss = (0, _index.makeDIDFromAddress)(address);
/* Sign and return the token */
var tokenSigner = new _jsontokens.TokenSigner('ES256k', privateKey);
token = tokenSigner.sign(payload);
}
return token;
}
function makeAuthResponse(privateKey) {
var profile = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var username = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var expiresAt = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : (0, _index.nextMonth)().getTime();
/* Convert the private key to a public key to an issuer */
var publicKey = _jsontokens.SECP256K1Client.derivePublicKey(privateKey);
var address = (0, _index.publicKeyToAddress)(publicKey);
/* Create the payload */
var payload = {
jti: (0, _index.makeUUID4)(),
iat: Math.floor(new Date().getTime() / 1000), // JWT times are in seconds
exp: Math.floor(expiresAt / 1000), // JWT times are in seconds
iss: (0, _index.makeDIDFromAddress)(address),
public_keys: [publicKey],
profile: profile,
username: username
};
/* Sign and return the token */
var tokenSigner = new _jsontokens.TokenSigner('ES256k', privateKey);
return tokenSigner.sign(payload);
}
function doSignaturesMatchPublicKeys(token) {
var payload = (0, _jsontokens.decodeToken)(token).payload;
var publicKeys = payload.public_keys;
if (publicKeys.length === 1) {
var publicKey = publicKeys[0];
try {
var tokenVerifier = new _jsontokens.TokenVerifier('ES256k', publicKey);
var signatureVerified = tokenVerifier.verify(token);
if (signatureVerified) {
return true;
} else {
return false;
}
} catch (e) {
return false;
}
} else {
throw new Error('Multiple public keys are not supported');
}
}
function doPublicKeysMatchIssuer(token) {
var payload = (0, _jsontokens.decodeToken)(token).payload;
var publicKeys = payload.public_keys;
var addressFromIssuer = (0, _index.getAddressFromDID)(payload.iss);
if (publicKeys.length === 1) {
var addressFromPublicKeys = (0, _index.publicKeyToAddress)(publicKeys[0]);
if (addressFromPublicKeys === addressFromIssuer) {
return true;
}
} else {
throw new Error('Multiple public keys are not supported');
}
return false;
}
function doPublicKeysMatchUsername(token, nameLookupURL) {
return new Promise(function (resolve, reject) {
var payload = (0, _jsontokens.decodeToken)(token).payload;
if (!payload.username) {
resolve(true);
return;
}
if (payload.username === null) {
resolve(true);
return;
}
if (nameLookupURL === null) {
resolve(false);
return;
}
var username = payload.username;
var url = nameLookupURL.replace(/\/$/, "") + '/' + username;
try {
fetch(url).then(function (response) {
return response.text();
}).then(function (responseText) {
return JSON.parse(responseText);
}).then(function (responseJSON) {
if (responseJSON.hasOwnProperty('address')) {
var nameOwningAddress = responseJSON.address;
var addressFromIssuer = (0, _index.getAddressFromDID)(payload.iss);
if (nameOwningAddress === addressFromIssuer) {
resolve(true);
} else {
resolve(false);
}
} else {
resolve(false);
}
}).catch(function (e) {
resolve(false);
});
} catch (e) {
resolve(false);
}
});
}
function isIssuanceDateValid(token) {
var payload = (0, _jsontokens.decodeToken)(token).payload;
if (payload.iat) {
if (typeof payload.iat !== "number") {
return false;
}
var issuedAt = new Date(payload.iat * 1000); // JWT times are in seconds
if (new Date().getTime() < issuedAt.getTime()) {
return false;
} else {
return true;
}
} else {
return true;
}
}
function isExpirationDateValid(token) {
var payload = (0, _jsontokens.decodeToken)(token).payload;
if (payload.exp) {
if (typeof payload.exp !== "number") {
return false;
}
var expiresAt = new Date(payload.exp * 1000); // JWT times are in seconds
if (new Date().getTime() > expiresAt.getTime()) {
return false;
} else {
return true;
}
} else {
return true;
}
}
function verifyAuthRequest(token) {
return new Promise(function (resolve, reject) {
if ((0, _jsontokens.decodeToken)(token).header.alg === 'none') {
reject("Token must be signed in order to be verified");
}
Promise.all([isExpirationDateValid(token), isIssuanceDateValid(token), doSignaturesMatchPublicKeys(token), doPublicKeysMatchIssuer(token)]).then(function (values) {
if (values.every(Boolean)) {
resolve(true);
} else {
resolve(false);
}
});
});
}
function verifyAuthResponse(token, nameLookupURL) {
return new Promise(function (resolve, reject) {
Promise.all([isExpirationDateValid(token), isIssuanceDateValid(token), doSignaturesMatchPublicKeys(token), doPublicKeysMatchIssuer(token), doPublicKeysMatchUsername(token)]).then(function (values) {
if (values.every(Boolean)) {
resolve(true);
} else {
resolve(false);
}
});
});
}
},{"../index":5,"isomorphic-fetch":160,"jsontokens":166}],3:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _authMessages = require('./authMessages');
Object.keys(_authMessages).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
return _authMessages[key];
}
});
});
var _authBrowser = require('./authBrowser');
Object.keys(_authBrowser).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
return _authBrowser[key];
}
});
});
},{"./authBrowser":1,"./authMessages":2}],4:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.makeDIDFromAddress = makeDIDFromAddress;
exports.makeDIDFromPublicKey = makeDIDFromPublicKey;
exports.getDIDType = getDIDType;
exports.getAddressFromDID = getAddressFromDID;
function makeDIDFromAddress(address) {
return 'did:btc-addr:' + address;
}
function makeDIDFromPublicKey(publicKey) {
return 'did:ecdsa-pub:' + publicKey;
}
function getDIDType(decentralizedID) {
var didParts = decentralizedID.split(':');
if (didParts.length !== 3) {
throw new InvalidDIDError('Decentralized IDs must have 3 parts');
}
if (didParts[0].toLowerCase() !== 'did') {
throw new InvalidDIDError('Decentralized IDs must start with "did"');
}
return didParts[1].toLowerCase();
}
function getAddressFromDID(decentralizedID) {
var didType = getDIDType(decentralizedID);
if (didType === 'btc-addr') {
return decentralizedID.split(':')[2];
} else {
return null;
}
}
/*
export function getPublicKeyOrAddressFromDID(decentralizedID) {
const didParts = decentralizedID.split(':')
if (didParts.length !== 3) {
throw new InvalidDIDError('Decentralized IDs must have 3 parts')
}
if (didParts[0].toLowerCase() !== 'did') {
throw new InvalidDIDError('Decentralized IDs must start with "did"')
}
if (didParts[1].toLowerCase() === 'ecdsa-pub') {
return didParts[2]
} else if (didParts[1].toLowerCase() === 'btc-addr') {
return didParts[2]
} else {
throw new InvalidDIDError('Decentralized ID format not supported')
}
}
*/
},{}],5:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _auth = require('./auth');
Object.keys(_auth).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
return _auth[key];
}
});
});
var _profiles = require('./profiles');
Object.keys(_profiles).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
return _profiles[key];
}
});
});
var _dids = require('./dids');
Object.defineProperty(exports, 'makeDIDFromAddress', {
enumerable: true,
get: function get() {
return _dids.makeDIDFromAddress;
}
});
Object.defineProperty(exports, 'makeDIDFromPublicKey', {
enumerable: true,
get: function get() {
return _dids.makeDIDFromPublicKey;
}
});
Object.defineProperty(exports, 'getDIDType', {
enumerable: true,
get: function get() {
return _dids.getDIDType;
}
});
Object.defineProperty(exports, 'getAddressFromDID', {
enumerable: true,
get: function get() {
return _dids.getAddressFromDID;
}
});
var _keys = require('./keys');
Object.defineProperty(exports, 'getEntropy', {
enumerable: true,
get: function get() {
return _keys.getEntropy;
}
});
Object.defineProperty(exports, 'makeECPrivateKey', {
enumerable: true,
get: function get() {
return _keys.makeECPrivateKey;
}
});
Object.defineProperty(exports, 'publicKeyToAddress', {
enumerable: true,
get: function get() {
return _keys.publicKeyToAddress;
}
});
var _utils = require('./utils');
Object.defineProperty(exports, 'nextYear', {
enumerable: true,
get: function get() {
return _utils.nextYear;
}
});
Object.defineProperty(exports, 'nextMonth', {
enumerable: true,
get: function get() {
return _utils.nextMonth;
}
});
Object.defineProperty(exports, 'nextHour', {
enumerable: true,
get: function get() {
return _utils.nextHour;
}
});
Object.defineProperty(exports, 'makeUUID4', {
enumerable: true,
get: function get() {
return _utils.makeUUID4;
}
});
Object.defineProperty(exports, 'hasprop', {
enumerable: true,
get: function get() {
return _utils.hasprop;
}
});
Object.defineProperty(exports, 'updateQueryStringParameter', {
enumerable: true,
get: function get() {
return _utils.updateQueryStringParameter;
}
});
var _jsontokens = require('jsontokens');
Object.defineProperty(exports, 'decodeToken', {
enumerable: true,
get: function get() {
return _jsontokens.decodeToken;
}
});
},{"./auth":3,"./dids":4,"./keys":6,"./profiles":7,"./utils":25,"jsontokens":166}],6:[function(require,module,exports){
(function (Buffer){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getEntropy = getEntropy;
exports.makeECPrivateKey = makeECPrivateKey;
exports.publicKeyToAddress = publicKeyToAddress;
var _crypto = require('crypto');
var _bitcoinjsLib = require('bitcoinjs-lib');
function getEntropy(numberOfBytes) {
if (!numberOfBytes) {
numberOfBytes = 32;
}
return (0, _crypto.randomBytes)(numberOfBytes);
}
function makeECPrivateKey() {
var keyPair = new _bitcoinjsLib.ECPair.makeRandom({ rng: getEntropy });
return keyPair.d.toBuffer(32).toString('hex');
}
function publicKeyToAddress(publicKey) {
var publicKeyBuffer = new Buffer(publicKey, 'hex');
var publicKeyHash160 = _bitcoinjsLib.crypto.hash160(publicKeyBuffer);
var address = _bitcoinjsLib.address.toBase58Check(publicKeyHash160, 0x00);
return address;
}
}).call(this,require("buffer").Buffer)
},{"bitcoinjs-lib":60,"buffer":105,"crypto":113}],7:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _profile = require('./profile');
Object.defineProperty(exports, 'Profile', {
enumerable: true,
get: function get() {
return _profile.Profile;
}
});
var _profileSchemas = require('./profileSchemas');
Object.defineProperty(exports, 'Person', {
enumerable: true,
get: function get() {
return _profileSchemas.Person;
}
});
Object.defineProperty(exports, 'Organization', {
enumerable: true,
get: function get() {
return _profileSchemas.Organization;
}
});
Object.defineProperty(exports, 'CreativeWork', {
enumerable: true,
get: function get() {
return _profileSchemas.CreativeWork;
}
});
Object.defineProperty(exports, 'resolveZoneFileToPerson', {
enumerable: true,
get: function get() {
return _profileSchemas.resolveZoneFileToPerson;
}
});
var _profileTokens = require('./profileTokens');
Object.defineProperty(exports, 'signProfileToken', {
enumerable: true,
get: function get() {
return _profileTokens.signProfileToken;
}
});
Object.defineProperty(exports, 'wrapProfileToken', {
enumerable: true,
get: function get() {
return _profileTokens.wrapProfileToken;
}
});
Object.defineProperty(exports, 'verifyProfileToken', {
enumerable: true,
get: function get() {
return _profileTokens.verifyProfileToken;
}
});
Object.defineProperty(exports, 'extractProfile', {
enumerable: true,
get: function get() {
return _profileTokens.extractProfile;
}
});
var _profileProofs = require('./profileProofs');
Object.defineProperty(exports, 'validateProofs', {
enumerable: true,
get: function get() {
return _profileProofs.validateProofs;
}
});
var _services = require('./services');
Object.defineProperty(exports, 'profileServices', {
enumerable: true,
get: function get() {
return _services.profileServices;
}
});
Object.defineProperty(exports, 'containsValidProofStatement', {
enumerable: true,
get: function get() {
return _services.containsValidProofStatement;
}
});
var _profileZoneFiles = require('./profileZoneFiles');
Object.defineProperty(exports, 'makeProfileZoneFile', {
enumerable: true,
get: function get() {
return _profileZoneFiles.makeProfileZoneFile;
}
});
Object.defineProperty(exports, 'getTokenFileUrl', {
enumerable: true,
get: function get() {
return _profileZoneFiles.getTokenFileUrl;
}
});
},{"./profile":8,"./profileProofs":9,"./profileSchemas":11,"./profileTokens":17,"./profileZoneFiles":18,"./services":21}],8:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Profile = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _schemaInspector = require('schema-inspector');
var _schemaInspector2 = _interopRequireDefault(_schemaInspector);
var _profileTokens = require('./profileTokens');
var _profileProofs = require('./profileProofs');
var _profileZoneFiles = require('./profileZoneFiles');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var schemaDefinition = {
type: 'object',
properties: {
'@context': { type: 'string', optional: true },
'@type': { type: 'string' }
}
};
var Profile = exports.Profile = function () {
function Profile() {
var profile = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, Profile);
this._profile = Object.assign({}, {
'@context': 'http://schema.org/'
}, profile);
}
_createClass(Profile, [{
key: 'toJSON',
value: function toJSON() {
return Object.assign({}, this._profile);
}
}, {
key: 'toToken',
value: function toToken(privateKey) {
return (0, _profileTokens.signProfileToken)(this.toJSON(), privateKey);
}
}], [{
key: 'validateSchema',
value: function validateSchema(profile) {
var strict = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
schemaDefinition['strict'] = strict;
return _schemaInspector2.default.validate(schemaDefinition, profile);
}
}, {
key: 'fromToken',
value: function fromToken(token) {
var publicKeyOrAddress = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var profile = (0, _profileTokens.extractProfile)(token, publicKeyOrAddress);
return new Profile(profile);
}
}, {
key: 'makeZoneFile',
value: function makeZoneFile(domainName, tokenFileURL) {
return (0, _profileZoneFiles.makeProfileZoneFile)(domainName, tokenFileURL);
}
}, {
key: 'validateProofs',
value: function validateProofs(domainName) {
return (0, _profileProofs.validateProofs)(this.toJSON(), domainName);
}
}]);
return Profile;
}();
},{"./profileProofs":9,"./profileTokens":17,"./profileZoneFiles":18,"schema-inspector":238}],9:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.validateProofs = validateProofs;
var _services = require('./services');
var validationTimeout = 30000; // 30 seconds
function validateProofs(profile, fqdn) {
if (!profile) {
throw new Error("Profile must not be null");
}
var promise = new Promise(function (resolve, reject) {
var proofs = [];
var accounts = [];
if (profile.hasOwnProperty("account")) {
accounts = profile.account;
} else {
resolve(proofs);
}
var accountsToValidate = accounts.length;
var timeoutTimer = setTimeout(function () {
console.error("Blockstack proof validation timed out.");
resolve(proofs);
}, validationTimeout);
accounts.forEach(function (account) {
// skip if proof service is not supported
if (account.hasOwnProperty("service") && !_services.profileServices.hasOwnProperty(account.service)) {
accountsToValidate--;
return;
}
if (!(account.hasOwnProperty("proofType") && account.proofType == "http" && account.hasOwnProperty("proofUrl"))) {
accountsToValidate--;
return;
}
var proof = {
"service": account.service,
"proof_url": account.proofUrl,
"identifier": account.identifier,
"valid": false
};
_services.profileServices[account.service].validateProof(proof, fqdn).then(function (proof) {
proofs.push(proof);
if (proofs.length >= accountsToValidate) {
clearTimeout(timeoutTimer);
resolve(proofs);
}
});
});
});
return promise;
}
},{"./services":21}],10:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CreativeWork = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _profileTokens = require('../profileTokens');
var _schemaInspector = require('schema-inspector');
var _schemaInspector2 = _interopRequireDefault(_schemaInspector);
var _profile = require('../profile');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var schemaDefinition = {
type: 'object',
properties: {
'@context': { type: 'string', optional: true },
'@type': { type: 'string' },
'@id': { type: 'string', optional: true }
}
};
var CreativeWork = exports.CreativeWork = function (_Profile) {
_inherits(CreativeWork, _Profile);
function CreativeWork() {
var profile = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, CreativeWork);
var _this = _possibleConstructorReturn(this, (CreativeWork.__proto__ || Object.getPrototypeOf(CreativeWork)).call(this, profile));
_this._profile = Object.assign({}, {
'@type': 'CreativeWork'
}, _this._profile);
return _this;
}
_createClass(CreativeWork, null, [{
key: 'validateSchema',
value: function validateSchema(profile) {
var strict = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
schemaDefinition['strict'] = strict;
return _schemaInspector2.default.validate(schemaDefinition, profile);
}
}, {
key: 'fromToken',
value: function fromToken(token) {
var publicKeyOrAddress = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var profile = (0, _profileTokens.extractToken)(token, publicKeyOrAddress);
return new CreativeWork(profile);
}
}]);
return CreativeWork;
}(_profile.Profile);
},{"../profile":8,"../profileTokens":17,"schema-inspector":238}],11:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _person = require('./person');
Object.defineProperty(exports, 'Person', {
enumerable: true,
get: function get() {
return _person.Person;
}
});
var _organization = require('./organization');
Object.defineProperty(exports, 'Organization', {
enumerable: true,
get: function get() {
return _organization.Organization;
}
});
var _creativework = require('./creativework');
Object.defineProperty(exports, 'CreativeWork', {
enumerable: true,
get: function get() {
return _creativework.CreativeWork;
}
});
var _personLegacy = require('./personLegacy');
Object.defineProperty(exports, 'getPersonFromLegacyFormat', {
enumerable: true,
get: function get() {
return _personLegacy.getPersonFromLegacyFormat;
}
});
var _personZoneFiles = require('./personZoneFiles');
Object.defineProperty(exports, 'resolveZoneFileToPerson', {
enumerable: true,
get: function get() {
return _personZoneFiles.resolveZoneFileToPerson;
}
});
},{"./creativework":10,"./organization":12,"./person":13,"./personLegacy":14,"./personZoneFiles":16}],12:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Organization = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _schemaInspector = require('schema-inspector');
var _schemaInspector2 = _interopRequireDefault(_schemaInspector);
var _profileTokens = require('../profileTokens');
var _profile = require('../profile');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var schemaDefinition = {
type: 'object',
properties: {
'@context': { type: 'string', optional: true },
'@type': { type: 'string' },
'@id': { type: 'string', optional: true }
}
};
var Organization = exports.Organization = function (_Profile) {
_inherits(Organization, _Profile);
function Organization() {
var profile = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, Organization);
var _this = _possibleConstructorReturn(this, (Organization.__proto__ || Object.getPrototypeOf(Organization)).call(this, profile));
_this._profile = Object.assign({}, {
'@type': 'Organization'
}, _this._profile);
return _this;
}
_createClass(Organization, null, [{
key: 'validateSchema',
value: function validateSchema(profile) {
var strict = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
schemaDefinition['strict'] = strict;
return _schemaInspector2.default.validate(schemaDefinition, profile);
}
}, {
key: 'fromToken',
value: function fromToken(token) {
var publicKeyOrAddress = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var profile = (0, _profileTokens.extractProfile)(token, publicKeyOrAddress);
return new Organization(profile);
}
}]);
return Organization;
}(_profile.Profile);
},{"../profile":8,"../profileTokens":17,"schema-inspector":238}],13:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Person = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _schemaInspector = require('schema-inspector');
var _schemaInspector2 = _interopRequireDefault(_schemaInspector);
var _profile = require('../profile');
var _profileTokens = require('../profileTokens');
var _personLegacy = require('./personLegacy');
var _personUtils = require('./personUtils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var schemaDefinition = {
type: 'object',
strict: false,
properties: {
'@context': { type: 'string', optional: true },
'@type': { type: 'string' },
'@id': { type: 'string', optional: true },
name: { type: 'string', optional: true },
givenName: { type: 'string', optional: true },
familyName: { type: 'string', optional: true },
description: { type: 'string', optional: true },
image: {
type: 'array',
optional: true,
items: {
type: 'object',
properties: {
'@type': { type: 'string' },
'name': { type: 'string', optional: true },
'contentUrl': { type: 'string', optional: true }
}
}
},
website: {
type: 'array',
optional: true,
items: {
type: 'object',
properties: {
'@type': { type: 'string' },
'url': { type: 'string', optional: true }
}
}
},
account: {
type: 'array',
optional: true,
items: {
type: 'object',
properties: {
'@type': { type: 'string' },
'service': { type: 'string', optional: true },
'identifier': { type: 'string', optional: true },
'proofType': { type: 'string', optional: true },
'proofUrl': { type: 'string', optional: true },
'proofMessage': { type: 'string', optional: true },
'proofSignature': { type: 'string', optional: true }
}
}
},
worksFor: {
type: 'array',
optional: true,
items: {
type: 'object',
properties: {
'@type': { type: 'string' },
'@id': { type: 'string', optional: true }
}
}
},
knows: {
type: 'array',
optional: true,
items: {
type: 'object',
properties: {
'@type': { type: 'string' },
'@id': { type: 'string', optional: true }
}
}
},
address: {
type: 'object',
optional: true,
properties: {
'@type': { type: 'string' },
'streetAddress': { type: 'string', optional: true },
'addressLocality': { type: 'string', optional: true },
'postalCode': { type: 'string', optional: true },
'addressCountry': { type: 'string', optional: true }
}
},
birthDate: { type: 'string', optional: true },
taxID: { type: 'string', optional: true }
}
};
var Person = exports.Person = function (_Profile) {
_inherits(Person, _Profile);
function Person() {
var profile = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, Person);
var _this = _possibleConstructorReturn(this, (Person.__proto__ || Object.getPrototypeOf(Person)).call(this, profile));
_this._profile = Object.assign({}, {
'@type': 'Person'
}, _this._profile);
return _this;
}
_createClass(Person, [{
key: 'profile',
value: function profile() {
return Object.assign({}, this._profile);
}
}, {
key: 'name',
value: function name() {
return (0, _personUtils.getName)(this.profile());
}
}, {
key: 'givenName',
value: function givenName() {
return (0, _personUtils.getGivenName)(this.profile());
}
}, {
key: 'familyName',
value: function familyName() {
return (0, _personUtils.getFamilyName)(this.profile());
}
}, {
key: 'description',
value: function description() {
return (0, _personUtils.getDescription)(this.profile());
}
}, {
key: 'avatarUrl',
value: function avatarUrl() {
return (0, _personUtils.getAvatarUrl)(this.profile());
}
}, {
key: 'verifiedAccounts',
value: function verifiedAccounts(verifications) {
return (0, _personUtils.getVerifiedAccounts)(this.profile(), verifications);
}
}, {
key: 'address',
value: function address() {
return (0, _personUtils.getAddress)(this.profile());
}
}, {
key: 'birthDate',
value: function birthDate() {
return (0, _personUtils.getBirthDate)(this.profile());
}
}, {
key: 'connections',
value: function connections() {
return (0, _personUtils.getConnections)(this.profile());
}
}, {
key: 'organizations',
value: function organizations() {
return (0, _personUtils.getOrganizations)(this.profile());
}
}], [{
key: 'validateSchema',
value: function validateSchema(profile) {
var strict = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
schemaDefinition['strict'] = strict;
return _schemaInspector2.default.validate(schemaDefinition, profile);
}
}, {
key: 'fromToken',
value: function fromToken(token) {
var publicKeyOrAddress = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var profile = (0, _profileTokens.extractProfile)(token, publicKeyOrAddress);
return new Person(profile);
}
}, {
key: 'fromLegacyFormat',
value: function fromLegacyFormat(legacyProfile) {
var profile = (0, _personLegacy.getPersonFromLegacyFormat)(legacyProfile);
return new Person(profile);
}
}]);
return Person;
}(_profile.Profile);
},{"../profile":8,"../profileTokens":17,"./personLegacy":14,"./personUtils":15,"schema-inspector":238}],14:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getPersonFromLegacyFormat = getPersonFromLegacyFormat;
var _index = require('../../index');
function formatAccount(serviceName, data) {
var proofUrl = void 0;
if ((0, _index.hasprop)(data, 'proof.url')) {
proofUrl = data.proof.url;
}
return {
"@type": "Account",
"service": serviceName,
"identifier": data.username,
"proofType": "http",
"proofUrl": proofUrl
};
}
function getPersonFromLegacyFormat(profile) {
var profileData = {
"@type": "Person"
};
if ((0, _index.hasprop)(profile, 'name.formatted')) {
profileData.name = profile.name.formatted;
}
if ((0, _index.hasprop)(profile, 'bio')) {
profileData.description = profile.bio;
}
if ((0, _index.hasprop)(profile, 'location.formatted')) {
profileData.address = {
"@type": "PostalAddress",
"addressLocality": profile.location.formatted
};
}
var images = [];
if ((0, _index.hasprop)(profile, 'avatar.url')) {
images.push({
"@type": "ImageObject",
"name": "avatar",
"contentUrl": profile.avatar.url
});
}
if ((0, _index.hasprop)(profile, 'cover.url')) {
images.push({
"@type": "ImageObject",
"name": "cover",
"contentUrl": profile.cover.url
});
}
if (images.length) {
profileData.image = images;
}
if ((0, _index.hasprop)(profile, 'website')) {
profileData.website = [{
"@type": "WebSite",
"url": profile.website
}];
}
var accounts = [];
if ((0, _index.hasprop)(profile, 'bitcoin.address')) {
accounts.push({
"@type": "Account",
"role": "payment",
"service": "bitcoin",
"identifier": profile.bitcoin.address
});
}
if ((0, _index.hasprop)(profile, 'twitter.username')) {
accounts.push(formatAccount('twitter', profile.twitter));
}
if ((0, _index.hasprop)(profile, 'facebook.username')) {
accounts.push(formatAccount('facebook', profile.facebook));
}
if ((0, _index.hasprop)(profile, 'github.username')) {
accounts.push(formatAccount('github', profile.github));
}
if ((0, _index.hasprop)(profile, 'auth')) {
if (profile.auth.length > 0) {
if ((0, _index.hasprop)(profile.auth[0], 'publicKeychain')) {
accounts.push({
"@type": "Account",
"role": "key",
"service": "bip32",
"identifier": profile.auth[0].publicKeychain
});
}
}
}
if ((0, _index.hasprop)(profile, 'pgp.url')) {
accounts.push({
"@type": "Account",
"role": "key",
"service": "pgp",
"identifier": profile.pgp.fingerprint,
"contentUrl": profile.pgp.url
});
}
profileData.account = accounts;
return profileData;
}
},{"../../index":5}],15:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getName = getName;
exports.getGivenName = getGivenName;
exports.getFamilyName = getFamilyName;
exports.getDescription = getDescription;
exports.getAvatarUrl = getAvatarUrl;
exports.getVerifiedAccounts = getVerifiedAccounts;
exports.getOrganizations = getOrganizations;
exports.getConnections = getConnections;
exports.getAddress = getAddress;
exports.getBirthDate = getBirthDate;
function getName(profile) {
if (!profile) {
return null;
}
var name = null;
if (profile.givenName || profile.familyName) {
name = '';
if (profile.givenName) {
name = profile.givenName;
}
if (profile.familyName) {
name += ' ' + profile.familyName;
}
} else if (profile.name) {
name = profile.name;
}
return name;
}
function getGivenName(profile) {
if (!profile) {
return null;
}
var givenName = null;
if (profile.givenName) {
givenName = profile.givenName;
} else if (profile.name) {
var nameParts = profile.name.split(' ');
givenName = nameParts.slice(0, -1).join(' ');
}
return givenName;
}
function getFamilyName(profile) {
if (!profile) {
return null;
}
var familyName = null;
if (profile.familyName) {
familyName = profile.familyName;
} else if (profile.name) {
var nameParts = profile.name.split(' ');
familyName = nameParts.pop();
}
return familyName;
}
function getDescription(profile) {
if (!profile) {
return null;
}
var description = null;
if (profile.description) {
description = profile.description;
}
return description;
}
function getAvatarUrl(profile) {
if (!profile) {
return null;
}
var avatarContentUrl = null;
if (profile.image) {
profile.image.map(function (image) {
if (image.name === 'avatar') {
avatarContentUrl = image.contentUrl;
return;
}
});
}
return avatarContentUrl;
}
function getVerifiedAccounts(profile, verifications) {
if (!profile) {
return null;
}
var filteredAccounts = [];
if (profile.hasOwnProperty('account') && verifications) {
profile.account.map(function (account) {
var accountIsValid = false;
var proofUrl = null;
verifications.map(function (verification) {
if (verification.hasOwnProperty('proof_url')) {
verification.proofUrl = verification.proof_url;
}
if (verification.valid && verification.service === account.service && verification.identifier === account.identifier && verification.proofUrl) {
accountIsValid = true;
proofUrl = verification.proofUrl;
}
});
if (accountIsValid) {
account.proofUrl = proofUrl;
filteredAccounts.push(account);
}
});
}
return filteredAccounts;
}
function getOrganizations(profile) {
if (!profile) {
return null;
}
var organizations = [];
if (profile.hasOwnProperty('worksFor')) {
return profile.worksFor;
}
return organizations;
}
function getConnections(profile) {
if (!profile) {
return null;
}
var connections = [];
if (profile.hasOwnProperty('knows')) {
connections = profile.knows;
}
return connections;
}
function getAddress(profile) {
if (!profile) {
return null;
}
var addressString = null;
if (profile.hasOwnProperty('address')) {
var addressParts = [];
if (profile.address.hasOwnProperty('streetAddress')) {
addressParts.push(profile.address.streetAddress);
}
if (profile.address.hasOwnProperty('addressLocality')) {
addressParts.push(profile.address.addressLocality);
}
if (profile.address.hasOwnProperty('postalCode')) {
addressParts.push(profile.address.postalCode);
}
if (profile.address.hasOwnProperty('addressCountry')) {
addressParts.push(profile.address.addressCountry);
}
if (addressParts.length) {
addressString = addressParts.join(', ');
}
}
return addressString;
}
function getBirthDate(profile) {
if (!profile) {
return null;
}
var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var birthDateString = null;
if (profile.hasOwnProperty('birthDate')) {
var date = new Date(profile.birthDate);
birthDateString = monthNames[date.getMonth()] + ' ' + date.getDate() + ', ' + date.getFullYear();
}
return birthDateString;
}
},{}],16:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.resolveZoneFileToPerson = resolveZoneFileToPerson;
var _zoneFile = require('zone-file');
var _person = require('./person');
var _profileZoneFiles = require('../profileZoneFiles');
var _profileTokens = require('../profileTokens');
function resolveZoneFileToPerson(zoneFile, publicKeyOrAddress, callback) {
var zoneFileJson = null;
try {
zoneFileJson = (0, _zoneFile.parseZoneFile)(zoneFile);
if (!zoneFileJson.has