UNPKG

koa-session-dynamodb-store

Version:

The DynamoDB extension store for koa-session.

1 lines 7.02 kB
"use strict";exports.__esModule=true;exports.default=void 0;var _awsSdk=_interopRequireDefault(require("aws-sdk"));var _constants=require("./constants");var _utils=require("./utils");function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}}function _asyncToGenerator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(undefined)})}}function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key]}}}return target};return _extends.apply(this,arguments)}const RESOURCE_NOT_FOUND_EXCEPTION="ResourceNotFoundException";class DynamoDBStore{constructor(options={},callback=_constants.DEFAULT_CALLBACK){(0,_utils.debug)("Initializing store",options);this.setOptions(options);const dynamoConfig=options.dynamoConfig||{};this.dynamoService=new _awsSdk.default.DynamoDB(_extends({},dynamoConfig,{apiVersion:_constants.API_VERSION}));this.documentClient=new _awsSdk.default.DynamoDB.DocumentClient({service:this.dynamoService});if(this.autoCreateTable){this.createTableIfDontExists(callback)}}setOptions(options){const{table={},dynamoConfig:{region=""}={}}=options;const{name=_constants.DEFAULT_TABLE_NAME,hashKey=_constants.DEFAULT_HASH_KEY,ttlKey=_constants.DEFAULT_TTL_KEY,readCapacityUnits=_constants.DEFAULT_RCU,writeCapacityUnits=_constants.DEFAULT_WCU,useTtlExpired=_constants.DEFAULT_USE_TTL_EXPIRED,autoCreate=_constants.DEFAULT_TABLE_AUTO_CREATE}=table;Object.assign(this,{tableName:name,autoCreateTable:autoCreate,hashKey,ttlKey,readCapacityUnits:Number(readCapacityUnits),writeCapacityUnits:Number(writeCapacityUnits),isLocal:region.indexOf("local")>=0,useTtlExpired})}isTableCreated(){var _this=this;return _asyncToGenerator(function*(){try{const describeTable=yield _this.dynamoService.describeTable({TableName:_this.tableName}).promise();(0,_utils.debug)("DecribeTable message : ",describeTable);const describeTimeToLive=yield _this.dynamoService.describeTimeToLive({TableName:_this.tableName}).promise();(0,_utils.debug)("DescribeTimeToLive message : ",describeTimeToLive);return{describeTable,describeTimeToLive}}catch(error){if(error.code!==RESOURCE_NOT_FOUND_EXCEPTION){throw error}return null}})()}createTable(){const params={TableName:this.tableName,KeySchema:[{AttributeName:this.hashKey,KeyType:"HASH"}],AttributeDefinitions:[{AttributeName:this.hashKey,AttributeType:"S"}],ProvisionedThroughput:{ReadCapacityUnits:this.readCapacityUnits,WriteCapacityUnits:this.writeCapacityUnits}};return this.dynamoService.createTable(params).promise()}updateTable(exists){const{Table:{ProvisionedThroughput:{ReadCapacityUnits:OldReadCapacityUnits,WriteCapacityUnits:OldWriteCapacityUnits}}}=exists.describeTable;const{readCapacityUnits:ReadCapacityUnits,writeCapacityUnits:WriteCapacityUnits}=this;const updated={};if(ReadCapacityUnits!==OldReadCapacityUnits||WriteCapacityUnits!==OldWriteCapacityUnits){updated.WriteCapacityUnits=WriteCapacityUnits;updated.ReadCapacityUnits=ReadCapacityUnits}const params={TableName:this.tableName,ProvisionedThroughput:_extends({},updated)};if(updated.ReadCapacityUnits||updated.WriteCapacityUnits){(0,_utils.debug)("UpdateTable params : ",params);return this.dynamoService.updateTable(params).promise()}(0,_utils.debug)("UpdateTable message : nothing to update.");return Promise.resolve(true)}setTtlField(){var _this2=this;return _asyncToGenerator(function*(){const{tableName,ttlKey}=_this2;const params={TableName:tableName,TimeToLiveSpecification:{AttributeName:ttlKey,Enabled:_this2.useTtlExpired}};return _this2.dynamoService.updateTimeToLive(params).promise()})()}createTableIfDontExists(callback){var _this3=this;return _asyncToGenerator(function*(){try{const exists=yield _this3.isTableCreated();if(!_this3.isLocal){if(exists){(0,_utils.debug)(`Table ${_this3.tableName} already exists`);const{TimeToLiveDescription:{AttributeName:attributeName="",TimeToLiveStatus:timeToLiveStatus}}=exists.describeTimeToLive;const isTimeToLiveStatus=timeToLiveStatus==="ENABLED";if(_this3.useTtlExpired&&isTimeToLiveStatus&&attributeName!==_this3.ttlKey){_this3.ttlKey=attributeName;(0,_utils.debug)(`The ttlKey Attribute and the TTL attribute of DynamoDB do not match. The TTL attribute currently set for DynamoDB is '${attributeName}'. In this case, place the value of the DynamoDB TTL attribute as a priority.`)}else if(isTimeToLiveStatus!==_this3.useTtlExpired){try{yield _this3.setTtlField();(0,_utils.debug)("UpdateTimeToLive message : You have set the TimeToLive property")}catch(e){(0,_utils.debug)("UpdateTimeToLive error message : There was a problem updating the TTL attribute. It may be due to too many TTL property changes, so please try again later.");(0,_utils.debug)("UpdateTimeToLive error message : ",e)}}}_this3.updateTable(exists)}else{(0,_utils.debug)(`Creating table ${_this3.tableName}...`);yield _this3.createTable();if(!_this3.isLocal&&_this3.useTtlExpired){const interval=setInterval(_asyncToGenerator(function*(){try{yield _this3.setTtlField();(0,_utils.debug)("UpdateTimeToLive message : You have set the TimeToLive property.");clearInterval(interval)}catch(e){(0,_utils.debug)("UpdateTimeToLive error message : ",e);if(e.code==="ResourceInUseException"||e.code==="ResourceNotFoundException"){(0,_utils.debug)("Retry UpdateTimeToLive")}else{clearInterval(interval)}}}),10000)}}callback()}catch(createTableError){(0,_utils.debug)(`Error creating table ${_this3.tableName}`,createTableError);callback(createTableError)}})()}get(id){var _this4=this;return _asyncToGenerator(function*(){const{tableName,hashKey}=_this4;try{return yield _this4.documentClient.get({Key:{[hashKey]:id},TableName:tableName}).promise().then(result=>{if(result.Item&&result.Item.session){return result.Item.session}return result.Item})}catch(err){throw new Error("Unable to get session.")}})()}set(id,session,maxAge){var _this5=this;return _asyncToGenerator(function*(){const{tableName,hashKey,ttlKey}=_this5;const Item={session};Item[hashKey]=id;Item[ttlKey]=(0,_utils.toSecondsEpoch)(_this5.getExpirationDate(maxAge));const params={TableName:tableName,Item};return _this5.documentClient.put(params).promise()})()}getExpirationDate(maxAge){const expirationDate=Date.now()+maxAge;return new Date(expirationDate)}destroy(id){var _this6=this;return _asyncToGenerator(function*(){const{tableName,hashKey}=_this6;return _this6.documentClient.delete({Key:{[hashKey]:id},TableName:tableName}).promise()})()}}exports.default=DynamoDBStore;