blockstack-storage
Version:
The Blockstack Javascript library for storage.
311 lines (254 loc) • 8.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getUserData = getUserData;
exports.getGaiaLocalData = getGaiaLocalData;
exports.setUserData = setUserData;
exports.setGaiaLocalData = setGaiaLocalData;
exports.getCachedMountContext = getCachedMountContext;
exports.setCachedMountContext = setCachedMountContext;
exports.deleteCachedMountContext = deleteCachedMountContext;
exports.getBlockchainIDFromSessionOrDefault = getBlockchainIDFromSessionOrDefault;
exports.getSessionToken = getSessionToken;
exports.getSessionBlockchainID = getSessionBlockchainID;
exports.getSessionDatastoreID = getSessionDatastoreID;
exports.getSessionAppName = getSessionAppName;
exports.getSessionDeviceID = getSessionDeviceID;
exports.getDeviceRootVersion = getDeviceRootVersion;
exports.putDeviceRootVersion = putDeviceRootVersion;
var _util = require('./util');
var LOCAL_STORAGE_ID = 'blockstack';
var LOCAL_STORAGE_GAIA_ID = 'blockstack-gaia';
var urlparse = require('url');
var crypto = require('crypto');
var jsontokens = require('jsontokens');
var assert = require('assert');
/*
* Get a reference to our localStorage implementation
*/
function getLocalStorage() {
return localStorage;
}
/*
* Get local storage object for Blockstack
* Throws on error
*/
function getUserData() {
var localStorage = getLocalStorage();
var userData = localStorage.getItem(LOCAL_STORAGE_ID);
if (userData === null || typeof userData === 'undefined') {
userData = '{}';
}
userData = JSON.parse(userData);
return userData;
}
/*
* Get Gaia-specific local data
* Throws on error
*/
function getGaiaLocalData() {
var localStorage = getLocalStorage();
var userData = localStorage.getItem(LOCAL_STORAGE_GAIA_ID);
if (userData === null || typeof userData === 'undefined') {
userData = '{}';
}
userData = JSON.parse(userData);
return userData;
}
/*
* Save local storage
*/
function setUserData(userData) {
var u = getUserData();
if (u.coreSessionToken && userData.coreSessionToken) {
// only store the newer one
var coreSessionToken = null;
if (u.coreSessionToken.timestamp < userData.coreSessionToken.timestamp) {
coreSessionToken = userData.coreSessionToken;
} else {
coreSessionToken = u.coreSessionToken;
}
userData.coreSessionToken = coreSessionToken;
}
localStorage.setItem(LOCAL_STORAGE_ID, JSON.stringify(userData));
}
/*
* Save local Gaia state
*/
function setGaiaLocalData(userData) {
localStorage.setItem(LOCAL_STORAGE_GAIA_ID, JSON.stringify(userData));
}
/*
* Get a cached app-specific datastore mount context for a given blockchain ID and application
* Return null if not found
* Throws on error
*/
function getCachedMountContext(blockchain_or_datastore_id, full_app_name) {
var userData = getUserData();
assert(userData);
assert(blockchain_or_datastore_id, 'No blockchain ID given');
assert(full_app_name, 'No app name given');
var cache_key = blockchain_or_datastore_id + '/' + full_app_name;
if (!userData.datastore_contexts) {
console.log("No datastore contexts defined");
return null;
}
if (!userData.datastore_contexts[cache_key]) {
console.log('No datastore contexts for ' + blockchain_or_datastore_id + ' in ' + full_app_name);
return null;
}
var ctx = userData.datastore_contexts[cache_key];
if (!ctx) {
console.log('Null datastore context for ' + blockchain_or_datastore_id + ' in ' + full_app_name);
return null;
}
return ctx;
}
/*
* Cache a mount context for a blockchain ID
*
* @param blockchain_or_datastore_id (string) the blockchain ID or datastore ID
* @param full_app_name (string) the fully-qualified application name
* @param datastore_context (object) the datastore mount context
*/
function setCachedMountContext(blockchain_or_datastore_id, full_app_name, datastore_context) {
var userData = getUserData();
assert(userData);
assert(blockchain_or_datastore_id, 'No blockchain ID given');
assert(full_app_name, 'No app name given');
if (!userData.datastore_contexts) {
userData.datastore_contexts = {};
}
var cache_key = blockchain_or_datastore_id + '/' + full_app_name;
userData.datastore_contexts[cache_key] = datastore_context;
setUserData(userData);
}
/*
* Uncache a mount context for a blockchain ID
*
* @param blockchain_or_datastore_id (string) the blockchain ID or datastore ID
* @param full_app_name (string) the fully-qualified application name
*/
function deleteCachedMountContext(blockchain_or_datastore_id, full_app_name) {
var userData = getUserData();
assert(userData);
assert(blockchain_or_datastore_id, 'No blockchain ID given');
assert(full_app_name, 'No app name given');
if (!userData.datastore_contexts) {
return true;
}
var cache_key = blockchain_or_datastore_id + '/' + full_app_name;
if (!Objects.keys(userData.datastore_contexts).includes(cache_key)) {
return true;
}
delete userData.datastore_contexts[cache_key];
setUserData(userData);
}
/*
* Get the blockchain ID from a session object, or generate a default one
* if no blockchain ID is set.
*
* @param session (object) the parsed session object
*
* Returns a string that is either the blockchain ID, or a deterministically-generated base64-encoded string
* that is consistent for the datastore
*/
function getBlockchainIDFromSessionOrDefault(session) {
if (!session.blockchain_id) {
assert(session.app_user_id, 'Missing app_user_id in ' + JSON.stringify(session));
return (0, _util.hashRawData)(Buffer.from(session.app_user_id).toString('base64'));
} else {
return session.blockchain_id;
}
}
/*
* Get the session token from localstorage
*/
function getSessionToken() {
var userData = getUserData();
assert(userData);
assert(userData.coreSessionToken);
var sessionToken = userData.coreSessionToken;
return sessionToken;
}
/*
* Get the current session's blockchain ID
*/
function getSessionBlockchainID() {
var sessionToken = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
if (!sessionToken) {
sessionToken = getSessionToken();
}
var session = jsontokens.decodeToken(sessionToken).payload;
return session.blockchain_id;
}
/*
* Get the current session's datastore ID
*/
function getSessionDatastoreID() {
var sessionToken = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
if (!sessionToken) {
sessionToken = getSessionToken();
}
var session = jsontokens.decodeToken(sessionToken).payload;
return session.app_user_id;
}
/*
* Get the fully-qualified application name from the session
*/
function getSessionAppName() {
var sessionToken = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
if (!sessionToken) {
sessionToken = getSessionToken();
}
var session = jsontokens.decodeToken(sessionToken).payload;
assert(session.app_domain, 'Missing app_domain in session ' + sessionToken);
var domainName = session.app_domain;
var urlInfo = urlparse.parse(domainName);
if (!urlInfo.slashes) {
domainName = 'http://' + domainName;
}
var appname = urlparse.parse(domainName).host;
assert(appname, 'Unparseable app_domain in session ' + sessionToken);
return appname;
}
/*
* Get the session's device ID
*/
function getSessionDeviceID() {
var sessionToken = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
if (!sessionToken) {
sessionToken = getSessionToken();
}
var session = jsontokens.decodeToken(sessionToken).payload;
return session.device_id;
}
/*
* Get the version of a device root page
*
* @param datastore_id (string) the datastore ID
* @param root_uuid (string) the root UUID
* @param device_ids (array) the list of device IDs
*
* Returns the version (integer) on success
* Returns 0 if we don't know
*/
function getDeviceRootVersion(datastore_id, root_uuid, device_ids) {
// TODO
return 0;
}
/*
* Put the version of a device root page
*
* @param datastore_id (string) the datastore ID
* @param root_uuid (string) the root UUID
* @param device_id (string) this device ID
* @version (integer) the version number
*
* returns True
*/
function putDeviceRootVersion(datastore_id, root_uuid, device_id, version) {
// TODO
return true;
}