copious-transitions
Version:
Framework for working with frameworks
301 lines (249 loc) • 14.4 kB
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: lib/session_token_manager.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: lib/session_token_manager.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>//
const AppLifeCycle = require("./general_lifecyle")
/// TokenTables
/**
* Top level abstraction defining the relationship between token users, and token storage which may refer to some DB.
*
* Provides access to token storage, making the semantics of token processing available to
* the authorization classes.
*
* This abstraction just fixes a handle to some DB interface and provides methods that wrap the token storage,
* which must be provided to the constructor.
*
* @memberof base
*/
class TokenTables extends AppLifeCycle {
constructor(db_obj,tokenStorage) {
super()
//
this.db = db_obj
// These are loosly written here. But, it may be good to keep
// a small number relative to session size id the backend is efficient
try {
this.tk_store = new tokenStorage(db_obj)
} catch (e) {
console.log(e)
}
}
/**
*
* @param {string} prefix
* @returns {string} - a token for a transition object
*/
generate_transition_token(prefix) {
return (this.tk_store.create_token(prefix))
}
/**
*
* @param {string} token
* @returns {any|Promise}
*/
token_to_key(token) {
let key = this.tk_store.from_token(token)
return key
}
/**
*
* @param {string} token
* @returns {boolean}
*/
async tokenCurrent(token) {
if ( token === undefined ) return(false)
let current = await this.tk_store.transition_token_is_active(token)
return ( current !== false )
}
}
/// SessionTokenManager
/**
*
* The Session Token Manager deals JSON objects arriving from some session oriented client.
* The JSON object is interned and stored as in the language's data object format.
* Certain fields may be expected in the data object. Methods for some default case are provided, but
* it is expected the application will override these methods and provide access for fields germain to the application.
*
* Provides basic methods for generating session tokens, stashing and unstashing.
*
* Manages a reference to a hashing method, called by `do_hash`.
*
* @extends TokenTables
*/
class SessionTokenManager extends TokenTables {
//
/**
*
* The configuration may bind the field `forhash` to a hashing function that will be used throughout the runtime.
*
* The db_obj is a reference to a class instance that knows how to talk to a database.
*
* The tokenStorage parameter is a required class reference that can generate a instance that manages tables of tokens.
*
* Initializes a table `release_session_data` for keeping data between client repsonses, where data comes from user objects,
* most likely obtained from the DB. In particular, the data will have a named field provided by `sess_data_accessor`. The data
* lasts until the user session is initialized by an authorization process, one that uses the general authorization (as opposed to
* light authorizatoin).
*
* @param {object} conf
* @param {object} db_obj
* @param {Class} tokenStorage
*/
constructor(conf,db_obj,tokenStorage) {
//
super(db_obj,tokenStorage) // token tables
//
this._sess_tok_hasher = (typeof conf.session_token_hasher === 'function') ? conf.session_token_hasher : this.#produce_hasher()
//
if ( conf ) {
this.hashables = clonify(conf.forhash) // clone the field map from the configuration.
} else {
this.hashables = { "field1" : "ucwid", "field2" : "timestamp" } // if these were not configured use something failry arbitrary
}
//
this.release_session_data = {} // if a session provides information for release on finalization, temporarily keep it here
}
/**
* Return the field name of the user object that references data that should be accessed as part of the session
*/
sess_data_accessor() { // likely to be overridden e.g. "_tracking"
return "app_user_data"
}
/**
* Access to a default hash function set globally for the application
*/
#produce_hasher() {
try {
if ( global_hash === undefined ) {
} else {
this._sess_tok_hasher = global_hash
}
} catch (e) {
}
}
/**
* Synonimic method to expose the hash function field, a configurable parameter
*
* @param {string} str
* @returns {string} - the hash of the string
*/
do_hash(str) { // default behavior --
return(this._sess_tok_hasher(str))
}
/**
* Makes a session token and returns it as a string
*
* >Uses access to a default hash function set globally for the application
*
* This method concatentates two informational parts and one nonce to make a parameter to a hash function
* in order to get a key that may be used as the session identifier.
*
* @param {object} post_body -- this is the JSON post body from the web application
*/
generate_session_token(post_body) {
let nonce = this.generate_transition_token();
//
let hash_part_1 = post_body[this.hashables.field1] // the field might no be supplied by the application
hash_part_1 = hash_part_1 ? hash_part_1 : "nothing1"
let hash_part_2 = post_body[this.hashables.field3] // the field might no be supplied by the application
hash_part_2 = hash_part_2 ? hash_part_2 : "nothing2"
//
let sess_tok = this.do_hash(hash_part_1 + hash_part_2 + nonce) // this is the session identifier just getting started.
return sess_tok
}
//
// stash_session_token
/**
* Stashes a session in the 'elements' map of the server-side transition object
*
* @param {object} user -- The user object is most likely extracted from the DB
* @param {object} transtion_object -- a nascent transition object that has both server side and client side aspects, but must contain the newly generated session token
*/
stash_session_token(user,transtion_object) { // sess_tok a made up token (app rule)
let sess_tok = transtion_object.session_token
let app_sess_data_access_fld = this.sess_data_accessor() // get the application identified field name that should occur in a user object
if ( app_sess_data_access_fld ) {
this.release_session_data[sess_tok] = user[app_sess_data_access_fld] // app overrides so that it knows this field (ucwid)
// The elements field will provide access to the session token (in turn to the user data) for the life the authorization transition
transtion_object.elements[app_sess_data_access_fld] = sess_tok // for secondary
}
}
// the stored transition object identified (mapped) by its token,
// will have the session token within the elements map object.
// see stash_session_token(user,transtion_object,sess_tok) in general_auth which extends this module
//
/**
* given the server side transition object for an authorization transition retrieve the sesssion token
* from the transition object's elements fields
*/
unstash_session_token(transObject) {
let key = this.sess_data_accessor()
if ( key ) {
return(transObject.elements[key])
}
return false
}
/**
* Calls upon token storage to save the session and the relationship to its owner.
*
* @param {string} key -- a key, mostly likely a ucwid that identifies an owner of the session
* @param {string} session_token -- a session token (should be made by generate_session_token)
*/
async addSession(key,session_token) { // e.g. ucwid and server side hash
if ( (key !== undefined) && (session_token !== undefined) ) {
this.tk_store.add_session(session_token,key) // ucwid, stashed token -> stashed token, ucwid
}
}
/**
* Calls upon token storage to termiate a session and the tokens that expire with its termination.
* The parameter passed is the session's transition token, which had been created for authorization transitions.
* The parameter is used to obtain the session token.
*
* @param {string} token -- the session's authorization transition token.
*/
destroySession(token) {
this.tk_store.destroy_session(token)
}
/**
* Checks to see if a session is current.
* The source key may be supplied to check on the hash of owner related data.
*
* @param {string} session_token -- a session token (should be made by generate_session_token)
* @param {string} [src_key] -- data returned from storing the transition token
*/
async sessionCurrent(session_token,src_key) { // src_key is not in use in the general case
if ( src_key === undefined ) return(false)
let key = await this.tk_store.active_session(session_token,src_key) // src key might be a ucwid
return key
}
}
module.exports = SessionTokenManager</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Namespaces</h3><ul><li><a href="Contractual.html">Contractual</a></li><li><a href="CopiousTransitions.html">CopiousTransitions</a></li><li><a href="DefaultDB.html">DefaultDB</a></li><li><a href="base.html">base</a></li><li><a href="field_validators.html">field_validators</a></li></ul><h3>Classes</h3><ul><li><a href="Contractual.LocalTObjectCache.html">LocalTObjectCache</a></li><li><a href="Contractual.MimeHandling.html">MimeHandling</a></li><li><a href="Contractual.TransitionHandling.html">TransitionHandling</a></li><li><a href="Contractual.UserHandling.html">UserHandling</a></li><li><a href="CopiousTransitions.CopiousTransitions.html">CopiousTransitions</a></li><li><a href="DefaultDB.CustomizationMethodsByApplication.html">CustomizationMethodsByApplication</a></li><li><a href="DefaultDB.FauxInMemStore.html">FauxInMemStore</a></li><li><a href="DefaultDB.FileMapper.html">FileMapper</a></li><li><a href="DefaultDB.FilesAndRelays.html">FilesAndRelays</a></li><li><a href="DefaultDB.FilesAndRelays_base.html">FilesAndRelays_base</a></li><li><a href="DefaultDB.LocalStaticDB.html">LocalStaticDB</a></li><li><a href="DefaultDB.LocalStorageLifeCycle.html">LocalStorageLifeCycle</a></li><li><a href="DefaultDB.LocalStorageSerialization.html">LocalStorageSerialization</a></li><li><a href="DefaultDB.PageableMemStoreElement.html">PageableMemStoreElement</a></li><li><a href="DefaultDB.PersistenceContracts.html">PersistenceContracts</a></li><li><a href="DefaultDB.RemoteMessaging.html">RemoteMessaging</a></li><li><a href="DefaultDB.StaticDBDefault.html">StaticDBDefault</a></li><li><a href="GeneralUserDBWrapperImpl.html">GeneralUserDBWrapperImpl</a></li><li><a href="SessionTokenManager.html">SessionTokenManager</a></li><li><a href="base.DBClass.html">DBClass</a></li><li><a href="base.EndpointManager.html">EndpointManager</a></li><li><a href="base.GeneralAppLifeCycle.html">GeneralAppLifeCycle</a></li><li><a href="base.GeneralAuth.html">GeneralAuth</a></li><li><a href="base.GeneralBusiness.html">GeneralBusiness</a></li><li><a href="base.GeneralDynamic.html">GeneralDynamic</a></li><li><a href="base.GeneralMiddleWare.html">GeneralMiddleWare</a></li><li><a href="base.GeneralStatic.html">GeneralStatic</a></li><li><a href="base.GeneralTransitionEngImpl.html">GeneralTransitionEngImpl</a></li><li><a href="base.SessionManager.html">SessionManager</a></li><li><a href="base.SessionManager_Lite.html">SessionManager_Lite</a></li><li><a href="base.TaggedTransition.html">TaggedTransition</a></li><li><a href="base.TokenTables.html">TokenTables</a></li><li><a href="base.UserMessageEndpoint.html">UserMessageEndpoint</a></li><li><a href="base.WebSocketManager.html">WebSocketManager</a></li><li><a href="field_validators.DataLookupField.html">DataLookupField</a></li><li><a href="field_validators.EmailField.html">EmailField</a></li><li><a href="field_validators.EmailVerifyField.html">EmailVerifyField</a></li><li><a href="field_validators.FieldTest.html">FieldTest</a></li><li><a href="field_validators.FieldValidatorTools.html">FieldValidatorTools</a></li><li><a href="field_validators.ForeignAuth.html">ForeignAuth</a></li><li><a href="field_validators.GeneralValidator.html">GeneralValidator</a></li><li><a href="field_validators.LengthyAlphabetField.html">LengthyAlphabetField</a></li><li><a href="field_validators.LengthyDigitalField.html">LengthyDigitalField</a></li><li><a href="field_validators.LengthyField.html">LengthyField</a></li><li><a href="field_validators.LengthyStringField.html">LengthyStringField</a></li><li><a href="field_validators.PasswordField.html">PasswordField</a></li><li><a href="field_validators.PasswordVerifyField.html">PasswordVerifyField</a></li><li><a href="field_validators.TypeCheckField.html">TypeCheckField</a></li></ul><h3>Global</h3><ul><li><a href="global.html#generate_password_block">generate_password_block</a></li><li><a href="global.html#load_configuration">load_configuration</a></li><li><a href="global.html#load_parameters">load_parameters</a></li><li><a href="global.html#module_top">module_top</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> on Tue Oct 31 2023 17:32:59 GMT-0700 (Pacific Daylight Time)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>