diff --git a/core/src/dbtypes.ts b/core/src/dbtypes.ts index bf3bffd..609bc39 100644 --- a/core/src/dbtypes.ts +++ b/core/src/dbtypes.ts @@ -40,6 +40,13 @@ export type GetMessagesFact = Prom.Factory export type GetPlayerParams = string; export type GetPlayerFact = Prom.Factory; +export type GameKey = { gameKey: string; }; +export type AddGameKeyParams = GameKey; +export type AddGameKeyFact = Prom.Factory; + +export type GetGameKeyParams = string; +export type GetGameKeyFact = Prom.Factory; + export interface PromiseFactories extends DBCalls { send: Prom.Factory; } @@ -55,6 +62,8 @@ export interface DBCalls { getMessage: GetMessageFact; getMessages: GetMessagesFact; getPlayer: GetPlayerFact; + addGameKey: AddGameKeyFact; + getGameKey: GetGameKeyFact; } export type SendMessageParams = Message.MessageData; @@ -74,5 +83,7 @@ export function createPromiseFactories (calls: DBCalls, send: SendMessage) getMessage: calls.getMessage, getMessages: calls.getMessages, getPlayer: calls.getPlayer, + addGameKey: calls.addGameKey, + getGameKey: calls.getGameKey, }; } diff --git a/core/src/localdb.ts b/core/src/localdb.ts index ad7dfd1..c24107f 100644 --- a/core/src/localdb.ts +++ b/core/src/localdb.ts @@ -10,6 +10,7 @@ import Prom = require('./utils/promise'); export interface DBState { players: Map.Map; messages: Map.Map; + gameKeys: Map.Map; } export function createDB (): DBState @@ -17,6 +18,7 @@ export function createDB (): DBState return { players: {}, messages: {}, + gameKeys: {}, }; } @@ -53,6 +55,8 @@ export function createLocalDBCalls (db: DBState, timeoutMs: number) getMessage: factory(getMessage), getMessages: factory(getMessages), getPlayer: factory(getPlayer), + addGameKey: factory(addGameKey), + getGameKey: factory(getGameKey), }; } @@ -230,3 +234,31 @@ export function getPlayer ( const data = db.players[email] || null; return promise(null, data); } + +export function addGameKey ( + db: DBState, + key: DBTypes.AddGameKeyParams) +{ + let error: Error = undefined; + + const inUse = (db.gameKeys[key.gameKey] !== undefined); + + if (inUse) { + error = { + code: 'ADD GAME KEY', + message: 'could not add game key', + }; + } else { + db.gameKeys[key.gameKey] = key; + } + + return promise(error, key); +} + +export function getGameKey ( + db: DBState, + key: DBTypes.GetGameKeyParams) +{ + const data = db.gameKeys[key] || null; + return promise(null, data); +} diff --git a/server/src/config.ts b/server/src/config.ts index 8168da8..0e2927b 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -20,6 +20,7 @@ export interface ConfigState { debugDBTimeoutMs: number; messagesTableName: string; playersTableName: string; + gameKeyTableName: string; emailDomain: string; updateIntervalMs: number; content: { @@ -65,6 +66,7 @@ const debugConfig: ConfigState = { credentials: null, messagesTableName: 'message-dev', playersTableName: 'player-dev', + gameKeyTableName: 'game-key-dev', emailDomain: 'nsa.playtopsecret.com', updateIntervalMs: 1000, content: { @@ -92,6 +94,7 @@ const releaseConfig: ConfigState = { credentials: null, messagesTableName: 'message-dev', playersTableName: 'player-dev', + gameKeyTableName: 'game-key-dev', emailDomain: 'nsa.playtopsecret.com', updateIntervalMs: 1000, content: { diff --git a/server/src/dynamodb.ts b/server/src/dynamodb.ts index d94e14a..3cab867 100644 --- a/server/src/dynamodb.ts +++ b/server/src/dynamodb.ts @@ -30,6 +30,7 @@ export function createDynamoDBCalls (config: Config.ConfigState): DBTypes.DBCall const credentials = config.credentials; const messageTable = config.messagesTableName; const playerTable = config.playersTableName; + const gameKeyTable = config.gameKeyTableName; const accessKeyId = credentials.awsAccessKeyId; const secretAccessKey = credentials.awsSecretAccessKey; const region = credentials.awsRegion; @@ -47,6 +48,8 @@ export function createDynamoDBCalls (config: Config.ConfigState): DBTypes.DBCall deleteMessage: bind(doc, messageTable, deleteMessage), getMessage: bind(doc, messageTable, getMessage), getMessages: bind(doc, messageTable, getMessages), + addGameKey: bind(doc, gameKeyTable, addGameKey), + getGameKey: bind(doc, gameKeyTable, getGameKey), }; } @@ -288,6 +291,45 @@ export function deleteAllMessages ( ); }; +export function addGameKey ( + docClient: DynamoDoc, + gameKeyTableName: string, + key: DBTypes.AddGameKeyParams) +{ + const awsParams: DynamoDB.PutParams = { + Item: true, + TableName: gameKeyTableName, + ReturnValues: 'NONE', + }; + + return promise( + 'addGameKey', + docClient, + docClient.put, + awsParams, + () => key); +}; + +export function getGameKey ( + docClient: DynamoDoc, + gameKeyTableName: string, + gameKey: DBTypes.GetGameKeyParams) +{ + const awsParams: DynamoDB.GetParams = { + Key: { + gameKey, + }, + TableName: gameKeyTableName, + }; + + return promise( + 'getGameKey', + docClient, + docClient.get, + awsParams, + extractItem); +}; + export function extractAttributes (data: { Attributes: T }) { return data ? data.Attributes : null; diff --git a/test/helpers.ts b/test/helpers.ts index be1c597..e34fc2e 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -75,6 +75,11 @@ export function createMessage ( numberOfChildren); } +export function createGameKey () +{ + return { gameKey: 'test key' }; +} + export function testGameData () { const contentPath = 'content'; diff --git a/test/server.dynamodb.ts b/test/server.dynamodb.ts index e4f3905..3d33160 100644 --- a/test/server.dynamodb.ts +++ b/test/server.dynamodb.ts @@ -26,6 +26,7 @@ const modifiedPlayer = Helpers.assign(player, { utcOffset: 10 }); const message0 = TestHelpers.createMessage0(); const modifiedMessage0 = Helpers.assign(message0, { fallbackSent: true }); const message1 = TestHelpers.createMessage1(); +const key = TestHelpers.createGameKey(); describe('DB', function () { describe('addPlayer', function () { @@ -148,4 +149,18 @@ describe('DB', function () { ]); }) }); + + describe('addGameKey', function () { + it('should return new game key', function () { + const promise = db.addGameKey(key); + return Chai.assert.eventually.deepEqual(promise, key); + }) + }); + + describe('getGameKey', function () { + it('should return the game key', function () { + const promise = db.getGameKey(key.gameKey); + return Chai.assert.eventually.deepEqual(promise, key); + }) + }); }); diff --git a/test/server.localdb.ts b/test/server.localdb.ts index c9b2415..0862847 100644 --- a/test/server.localdb.ts +++ b/test/server.localdb.ts @@ -194,4 +194,24 @@ describe('DB', function () { ]); }) }); + + describe('addGameKey', function () { + it('should return the added key', function () { + const db = TestHelpers.createDB(); + const key = TestHelpers.createGameKey(); + const promise = db.addGameKey(key); + return Chai.assert.eventually.equal(promise, key); + }) + }); + + describe('getGameKey', function () { + it('should return the key', function () { + const db = TestHelpers.createDB(); + const key = TestHelpers.createGameKey(); + const promise = db.addGameKey(key).then(valid => + db.getGameKey(key.gameKey) + ); + return Chai.assert.eventually.equal(promise, key); + }) + }); });