fix: auto-load player object and place in request
authorxangelo <me@xangelo.ca>
Tue, 8 Aug 2023 14:46:40 +0000 (10:46 -0400)
committerxangelo <me@xangelo.ca>
Tue, 8 Aug 2023 14:46:40 +0000 (10:46 -0400)
src/server/api.ts
src/server/auth.ts
src/server/locations/healer/index.ts
src/server/views/fight.ts

index bd86f977d9eaae3652e87312803ccc74aae6da0f..b7e003326e35669b846b07bc09311704ce2c41d8 100644 (file)
@@ -21,7 +21,7 @@ import {getShopEquipment, getShopItem, listShopItems } from './shopEquipment';
 import {EquippedItemDetails} from '../shared/equipped';
 import {ArmourEquipmentSlot, EquipmentSlot} from '../shared/inventory';
 import { clearTravelPlan, completeTravel, getAllPaths, getAllServices, getCityDetails, getService, getTravelPlan, stepForward, travel } from './map';
-import { signup, login, authEndpoint } from './auth';
+import { signup, login, authEndpoint, AuthRequest } from './auth';
 import {db} from './lib/db';
 import { getPlayerSkills, getPlayerSkillsAsObject, updatePlayerSkills } from './skills';
 import {SkillID, Skills} from '../shared/skills';
@@ -380,29 +380,13 @@ async function fightRound(player: Player, monster: MonsterWithFaction,  data: {a
 app.use(healerRouter);
 
 
-app.get('/chat/history', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
+app.get('/chat/history', authEndpoint, async (req: AuthRequest, res: Response) => {
   let html = chatHistory.map(renderChatMessage);
 
   res.send(html.join("\n"));
 });
 
-app.post('/chat', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
+app.post('/chat', authEndpoint, async (req: AuthRequest, res: Response) => {
   const msg = req.body.message.trim();
 
   if(!msg || !msg.length) {
@@ -434,7 +418,7 @@ app.post('/chat', authEndpoint, async (req: Request, res: Response) => {
 
   }
   else {
-    message = broadcastMessage(player.username, msg);
+    message = broadcastMessage(req.player.username, msg);
     chatHistory.push(message);
     chatHistory.slice(-10);
 
@@ -448,62 +432,30 @@ app.post('/chat', authEndpoint, async (req: Request, res: Response) => {
 
 });
 
-app.get('/player', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
+app.get('/player', authEndpoint, async (req: AuthRequest, res: Response) => {
+  const inventory = await getEquippedItems(req.player.id);
 
-  const inventory = await getEquippedItems(player.id);
-
-  res.send(renderPlayerBar(player, inventory) + (await renderProfilePage(player)));
+  res.send(renderPlayerBar(req.player, inventory) + (await renderProfilePage(req.player)));
 });
 
-app.get('/player/skills', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
-  const skills = await getPlayerSkills(player.id);
+app.get('/player/skills', authEndpoint, async (req: AuthRequest, res: Response) => {
+  const skills = await getPlayerSkills(req.player.id);
 
   res.send(renderSkills(skills));
 });
 
-app.get('/player/inventory', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
+app.get('/player/inventory', authEndpoint, async (req: AuthRequest, res: Response) => {
   const [inventory, items] = await Promise.all([
-    getInventory(player.id),
-    getPlayersItems(player.id)
+    getInventory(req.player.id),
+    getPlayersItems(req.player.id)
   ]);
 
   res.send(renderInventoryPage(inventory, items));
 });
 
-app.post('/player/equip/:item_id/:slot', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
-  const inventoryItem = await getInventoryItem(player.id, req.params.item_id);
-  const equippedItems = await getEquippedItems(player.id);
+app.post('/player/equip/:item_id/:slot', authEndpoint, async (req: AuthRequest, res: Response) => {
+  const inventoryItem = await getInventoryItem(req.player.id, req.params.item_id);
+  const equippedItems = await getEquippedItems(req.player.id);
   const requestedSlot = req.params.slot;
   let desiredSlot: EquipmentSlot = inventoryItem.equipment_slot;
 
@@ -533,9 +485,9 @@ app.post('/player/equip/:item_id/:slot', authEndpoint, async (req: Request, res:
     }
 
 
-    await equip(player.id, inventoryItem, desiredSlot);
-    const socketId = cache.get(`socket:${player.id}`).toString();
-    io.to(socketId).emit('updatePlayer', player);
+    await equip(req.player.id, inventoryItem, desiredSlot);
+    const socketId = cache.get(`socket:${req.player.id}`).toString();
+    io.to(socketId).emit('updatePlayer', req.player);
     io.to(socketId).emit('alert', {
       type: 'success',
       text: `You equipped your ${inventoryItem.name}`
@@ -546,47 +498,30 @@ app.post('/player/equip/:item_id/:slot', authEndpoint, async (req: Request, res:
   }
 
   const [inventory, items] = await Promise.all([
-    getInventory(player.id),
-    getPlayersItems(player.id)
+    getInventory(req.player.id),
+    getPlayersItems(req.player.id)
   ]);
 
-  res.send(renderInventoryPage(inventory, items, inventoryItem.type) + renderPlayerBar(player, inventory));
+  res.send(renderInventoryPage(inventory, items, inventoryItem.type) + renderPlayerBar(req.player, inventory));
 });
 
-app.post('/player/unequip/:item_id', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
+app.post('/player/unequip/:item_id', authEndpoint, async (req: AuthRequest, res: Response) => {
   const [item, ] = await Promise.all([
-    getInventoryItem(player.id, req.params.item_id),
-    unequip(player.id, req.params.item_id)
+    getInventoryItem(req.player.id, req.params.item_id),
+    unequip(req.player.id, req.params.item_id)
   ]);
 
   const [inventory, items] = await Promise.all([
-    getInventory(player.id),
-    getPlayersItems(player.id)
+    getInventory(req.player.id),
+    getPlayersItems(req.player.id)
   ]);
 
-  res.send(renderInventoryPage(inventory, items, item.type) + renderPlayerBar(player, inventory));
+  res.send(renderInventoryPage(inventory, items, item.type) + renderPlayerBar(req.player, inventory));
 });
 
-app.get('/player/explore', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
-
-  const fight = await loadMonsterFromFight(player.id);
-  let closestTown = player.city_id;
+app.get('/player/explore', authEndpoint, async (req: AuthRequest, res: Response) => {
+  const fight = await loadMonsterFromFight(req.player.id);
+  let closestTown = req.player.city_id;
 
   if(fight) {
     // ok lets display the fight screen!
@@ -602,10 +537,10 @@ app.get('/player/explore', authEndpoint, async (req: Request, res: Response) =>
     res.send(renderFight(data));
   }
   else {
-    const travelPlan = await getTravelPlan(player.id);
+    const travelPlan = await getTravelPlan(req.player.id);
     if(travelPlan) {
       // traveling!
-      const travelPlan = await getTravelPlan(player.id);
+      const travelPlan = await getTravelPlan(req.player.id);
 
       const closest: number = (travelPlan.current_position / travelPlan.total_distance) > 0.5 ? travelPlan.destination_id : travelPlan.source_id;
 
@@ -617,7 +552,7 @@ app.get('/player/explore', authEndpoint, async (req: Request, res: Response) =>
       }
 
       // STEP_DELAY
-      const nextAction = cache[`step:${player.id}`] || 0;
+      const nextAction = cache[`step:${req.player.id}`] || 0;
 
       res.send(renderTravel({
         things,
@@ -629,9 +564,9 @@ app.get('/player/explore', authEndpoint, async (req: Request, res: Response) =>
     else {
       // display the city info!
       const [city, locations, paths] = await Promise.all([
-        getCityDetails(player.city_id),
-        getAllServices(player.city_id),
-        getAllPaths(player.city_id)
+        getCityDetails(req.player.city_id),
+        getAllServices(req.player.city_id),
+        getAllPaths(req.player.city_id)
       ]);
 
       res.send(await renderMap({city, locations, paths}, closestTown));
@@ -641,14 +576,7 @@ app.get('/player/explore', authEndpoint, async (req: Request, res: Response) =>
 });
 
 // used to purchase equipment from a particular shop
-app.put('/location/:location_id/equipment/:item_id', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
+app.put('/location/:location_id/equipment/:item_id', authEndpoint, async (req: AuthRequest, res: Response) => {
   const item = await getShopEquipment(parseInt(req.params.item_id), parseInt(req.params.location_id));
 
   if(!item) {
@@ -656,30 +584,23 @@ app.put('/location/:location_id/equipment/:item_id', authEndpoint, async (req: R
     return res.sendStatus(400);
   }
 
-  if(player.gold < item.cost) {
+  if(req.player.gold < item.cost) {
     res.send(Alert.ErrorAlert(`Sorry, you need at least ${item.cost.toLocaleString()}G to purchase this.`));
     return;
   }
 
-  player.gold -= item.cost;
+  req.player.gold -= item.cost;
 
-  await updatePlayer(player);
-  await addInventoryItem(player.id, item);
+  await updatePlayer(req.player);
+  await addInventoryItem(req.player.id, item);
 
-  const equippedItems = await getEquippedItems(player.id);
+  const equippedItems = await getEquippedItems(req.player.id);
 
-  res.send(renderPlayerBar(player, equippedItems) + Alert.SuccessAlert(`You purchased ${item.name}`));
+  res.send(renderPlayerBar(req.player, equippedItems) + Alert.SuccessAlert(`You purchased ${item.name}`));
 });
 
 // used to purchase items from a particular shop
-app.put('/location/:location_id/items/:item_id', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
+app.put('/location/:location_id/items/:item_id', authEndpoint, async (req: AuthRequest, res: Response) => {
   const item: (ShopItem & Item) = await getItemFromShop(parseInt(req.params.item_id), parseInt(req.params.location_id));
 
   if(!item) {
@@ -687,32 +608,25 @@ app.put('/location/:location_id/items/:item_id', authEndpoint, async (req: Reque
     return res.sendStatus(400);
   }
 
-  if(player.gold < item.price_per_unit) {
+  if(req.player.gold < item.price_per_unit) {
     res.send(Alert.ErrorAlert(`Sorry, you need at least ${item.price_per_unit.toLocaleString()}G to purchase this.`));
     return;
   }
 
-  player.gold -= item.price_per_unit;
+  req.player.gold -= item.price_per_unit;
 
-  await updatePlayer(player);
-  await givePlayerItem(player.id, item.id, 1);
+  await updatePlayer(req.player);
+  await givePlayerItem(req.player.id, item.id, 1);
 
-  const equippedItems = await getEquippedItems(player.id);
+  const equippedItems = await getEquippedItems(req.player.id);
 
-  res.send(renderPlayerBar(player, equippedItems) + Alert.SuccessAlert(`You purchased a ${item.name}`));
+  res.send(renderPlayerBar(req.player, equippedItems) + Alert.SuccessAlert(`You purchased a ${item.name}`));
 });
 
 // used to display equipment modals in a store, validates that 
 // the equipment is actually in this store before displaying 
 // the modal
-app.get('/location/:location_id/equipment/:item_id/overview', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
+app.get('/location/:location_id/equipment/:item_id/overview', authEndpoint, async (req: AuthRequest, res: Response) => {
   const equipment = await getShopEquipment(parseInt(req.params.item_id), parseInt(req.params.location_id));
 
   if(!equipment) {
@@ -727,7 +641,7 @@ app.get('/location/:location_id/equipment/:item_id/overview', authEndpoint, asyn
       <img src="https://via.placeholder.com/64x64" title="${equipment.name}" alt="${equipment.name}"> 
     </div>
     <div>
-      ${renderEquipmentDetails(equipment, player)}
+      ${renderEquipmentDetails(equipment, req.player)}
     </div>
   </div>
   <div class="actions">
@@ -743,14 +657,7 @@ app.get('/location/:location_id/equipment/:item_id/overview', authEndpoint, asyn
 // used to display item modals in a store, validates that 
 // the item is actually in this store before displaying 
 // the modal
-app.get('/location/:location_id/items/:item_id/overview', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
+app.get('/location/:location_id/items/:item_id/overview', authEndpoint, async (req: AuthRequest, res: Response) => {
   const item: (ShopItem & Item) = await getItemFromShop(parseInt(req.params.item_id), parseInt(req.params.location_id));
 
   if(!item) {
@@ -779,15 +686,8 @@ app.get('/location/:location_id/items/:item_id/overview', authEndpoint, async (r
   res.send(html);
 });
 
-app.put('/item/:item_id', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
-  const item: PlayerItem = await getItemFromPlayer(player.id, parseInt(req.params.item_id));
+app.put('/item/:item_id', authEndpoint, async (req: AuthRequest, res: Response) => {
+  const item: PlayerItem = await getItemFromPlayer(req.player.id, parseInt(req.params.item_id));
 
   if(!item) {
     console.log(`Can't find item [${req.params.item_id}]`);
@@ -803,26 +703,26 @@ app.put('/item/:item_id', authEndpoint, async (req: Request, res: Response) => {
 
   switch(item.effect_name) {
     case 'heal_small':
-      const hpGain = HealthPotionSmall.effect(player);
+      const hpGain = HealthPotionSmall.effect(req.player);
 
-      player.hp += hpGain;
+      req.player.hp += hpGain;
 
-      if(player.hp > maxHp(player.constitution, player.level)) {
-        player.hp = maxHp(player.constitution, player.level);
+      if(req.player.hp > maxHp(req.player.constitution, req.player.level)) {
+        req.player.hp = maxHp(req.player.constitution, req.player.level);
       }
     break;
   }
 
-  await updateItemCount(player.id, item.item_id, -1);
-  await updatePlayer(player);
+  await updateItemCount(req.player.id, item.item_id, -1);
+  await updatePlayer(req.player);
 
-  const inventory = await getInventory(player.id);
+  const inventory = await getInventory(req.player.id);
   const equippedItems = inventory.filter(i => i.is_equipped);
-  const items = await getPlayersItems(player.id);
+  const items = await getPlayersItems(req.player.id);
 
   res.send(
     [
-      renderPlayerBar(player, equippedItems),
+      renderPlayerBar(req.player, equippedItems),
       renderInventoryPage(inventory, items, 'ITEMS'),
       Alert.SuccessAlert(`You used the ${item.name}`)
     ].join("")
@@ -830,15 +730,8 @@ app.put('/item/:item_id', authEndpoint, async (req: Request, res: Response) => {
 
 });
 
-app.get('/modal/items/:item_id', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
-  const item: PlayerItem = await getItemFromPlayer(player.id, parseInt(req.params.item_id));
+app.get('/modal/items/:item_id', authEndpoint, async (req: AuthRequest, res: Response) => {
+  const item: PlayerItem = await getItemFromPlayer(req.player.id, parseInt(req.params.item_id));
 
   if(!item) {
     logger.log(`Invalid item [${req.params.item_id}]`);
@@ -866,17 +759,10 @@ app.get('/modal/items/:item_id', authEndpoint, async (req: Request, res: Respons
   res.send(html);
 });
 
-app.get('/city/stores/city:stores/:location_id', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
+app.get('/city/stores/city:stores/:location_id', authEndpoint, async (req: AuthRequest, res: Response) => {
   const location = await getService(parseInt(req.params.location_id));
 
-  if(!location || location.city_id !== player.city_id) {
+  if(!location || location.city_id !== req.player.city_id) {
     logger.log(`Invalid location: [${req.params.location_id}]`);
     res.sendStatus(400);
   }
@@ -885,21 +771,14 @@ app.get('/city/stores/city:stores/:location_id', authEndpoint, async (req: Reque
     getShopItems(location.id)
   ]);
 
-  const html = await renderStore(shopEquipment, shopItems, player);
+  const html = await renderStore(shopEquipment, shopItems, req.player);
 
   res.send(html);
 });
 
-app.get('/city/explore/city:explore/:location_id', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
+app.get('/city/explore/city:explore/:location_id', authEndpoint, async (req: AuthRequest, res: Response) => {
   const location = await getService(parseInt(req.params.location_id));
-  if(!location || location.city_id !== player.city_id) {
+  if(!location || location.city_id !== req.player.city_id) {
 
     logger.log(`Invalid location: [${req.params.location_id}]`);
     res.sendStatus(400);
@@ -909,43 +788,28 @@ app.get('/city/explore/city:explore/:location_id', authEndpoint, async (req: Req
   res.send(renderMonsterSelector(monsters));
 });
 
-app.post('/travel', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
+app.post('/travel', authEndpoint, async (req: AuthRequest, res: Response) => {
   const destination_id = parseInt(req.body.destination_id);
 
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
   if(!destination_id || isNaN(destination_id)) {
     logger.log(`Invalid destination_id [${req.body.destination_id}]`);
     return res.sendStatus(400);
   }
 
-  const travelPlan = travel(player, req.body.destination_id);
+  const travelPlan = travel(req.player, req.body.destination_id);
 
   res.json(travelPlan);
 });
 
-app.post('/fight/turn', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
-  const monster = await loadMonsterWithFaction(player.id);
+app.post('/fight/turn', authEndpoint, async (req: AuthRequest, res: Response) => {
+  const monster = await loadMonsterWithFaction(req.player.id);
 
   if(!monster) {
     res.send(Alert.ErrorAlert('Not in a fight'));
     return;
   }
 
-  const fightData  = await fightRound(player, monster, {
+  const fightData  = await fightRound(req.player, monster, {
     action: req.body.action,
     target: req.body.fightTarget
   });
@@ -963,27 +827,19 @@ app.post('/fight/turn', authEndpoint, async (req: Request, res: Response) => {
   let travelSection = '';
   if(monster.fight_trigger === 'travel' && fightData.roundData.winner === 'player') {
     // you're travellinga dn you won.. display the keep walking!
-    const travelPlan = await getTravelPlan(player.id);
+    const travelPlan = await getTravelPlan(req.player.id);
     const closest: number = (travelPlan.current_position / travelPlan.total_distance) > 0.5 ? travelPlan.destination_id : travelPlan.source_id;
     travelSection = travelButton(0);
   }
 
-  const equippedItems = await getEquippedItems(player.id);
+  const equippedItems = await getEquippedItems(req.player.id);
   const playerBar = renderPlayerBar(fightData.player, equippedItems);
 
   res.send(html + travelSection + playerBar);
 });
 
-app.post('/fight', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
-  if(player.hp <= 0) {
+app.post('/fight', authEndpoint, async (req: AuthRequest, res: Response) => {
+  if(req.player.hp <= 0) {
     logger.log(`Player didn\'t have enough hp`);
     return res.sendStatus(400);
   }
@@ -1008,7 +864,7 @@ app.post('/fight', authEndpoint, async (req: Request, res: Response) => {
     return res.sendStatus(400);
   }
 
-  const fight = await createFight(player.id, monster, fightTrigger);
+  const fight = await createFight(req.player.id, monster, fightTrigger);
 
 
   const data: MonsterForFight = {
@@ -1023,17 +879,10 @@ app.post('/fight', authEndpoint, async (req: Request, res: Response) => {
   res.send(renderFight(data));
 });
 
-app.post('/travel/step', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-  const stepTimerKey = `step:${player.id}`;
-
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
+app.post('/travel/step', authEndpoint, async (req: AuthRequest, res: Response) => {
+  const stepTimerKey = `step:${req.player.id}`;
 
-  const travelPlan = await getTravelPlan(player.id);
+  const travelPlan = await getTravelPlan(req.player.id);
   if(!travelPlan) {
     res.send(Alert.ErrorAlert('You don\'t have a travel plan'));
     return;
@@ -1049,10 +898,10 @@ app.post('/travel/step', authEndpoint, async (req: Request, res: Response) => {
   travelPlan.current_position++;
 
   if(travelPlan.current_position >= travelPlan.total_distance) {
-    const travel = await completeTravel(player.id);
+    const travel = await completeTravel(req.player.id);
 
-    player.city_id = travel.destination_id;
-    await movePlayer(travel.destination_id, player.id);
+    req.player.city_id = travel.destination_id;
+    await movePlayer(travel.destination_id, req.player.id);
 
     const [city, locations, paths] = await Promise.all([
       getCityDetails(travel.destination_id),
@@ -1061,7 +910,7 @@ app.post('/travel/step', authEndpoint, async (req: Request, res: Response) => {
     ]);
 
     delete cache[stepTimerKey];
-    res.send(await renderMap({city, locations, paths}, player.city_id));
+    res.send(await renderMap({city, locations, paths}, req.player.city_id));
   }
   else {
     const walkingText: string[] = [
@@ -1070,7 +919,7 @@ app.post('/travel/step', authEndpoint, async (req: Request, res: Response) => {
     ];
     // update existing plan..
     // decide if they will run into anything
-    const travelPlan = await stepForward(player.id);
+    const travelPlan = await stepForward(req.player.id);
 
     const closest: number = (travelPlan.current_position / travelPlan.total_distance) > 0.5 ? travelPlan.destination_id : travelPlan.source_id;
 
@@ -1096,16 +945,8 @@ app.post('/travel/step', authEndpoint, async (req: Request, res: Response) => {
   }
 });
 
-app.post('/travel/:destination_id', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken'].toString();
-  const player: Player = await loadPlayer(authToken)
-
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
-  if(player.hp <= 0) {
+app.post('/travel/:destination_id', authEndpoint, async (req: AuthRequest, res: Response) => {
+  if(req.player.hp <= 0) {
     logger.log(`Player didn\'t have enough hp`);
     res.send(Alert.ErrorAlert('Sorry, you need some HP to start travelling.'));
     return;
@@ -1118,13 +959,13 @@ app.post('/travel/:destination_id', authEndpoint, async (req: Request, res: Resp
     return;
   }
 
-  await travel(player, destination.id);
+  await travel(req.player, destination.id);
 
   res.send(renderTravel({
     things: [],
     nextAction: 0,
     walkingText: '',
-    closestTown: player.city_id
+    closestTown: req.player.city_id
   }));
 });
 
index d82d4b64c39f06a9460a338fa1f8e3361bf61234..3f4899bad9decb1521c5ee4b31168b00927ad17e 100644 (file)
@@ -5,6 +5,10 @@ import { Auth } from '../shared/auth';
 import { db } from './lib/db';
 import { Request, Response } from 'express';
 
+export interface AuthRequest extends Request {
+  player: Player
+}
+
 export async function signup(playerId: string, username: string, password: string): Promise<void> {
   const salt = await bcrypt.genSalt(10);
   const hash = await bcrypt.hash(password, salt);
@@ -58,13 +62,21 @@ export async function login(username: string, password: string): Promise<Player>
 
 }
 
-export function authEndpoint(req: Request, res: Response, next: any) {
+export async function authEndpoint(req: AuthRequest, res: Response, next: any) {
   const authToken = req.headers['x-authtoken'];
   if(!authToken) {
     console.log(`Invalid auth token ${authToken}`);
-    res.sendStatus(400)
+    res.sendStatus(401)
   }
   else {
-    next()
+    const player: Player = await loadPlayer(authToken.toString());
+    if(player) {
+      req.player = player;
+      next()
+    }
+    else {
+      console.log(`Invalid auth token ${authToken}`);
+      res.sendStatus(401);
+    }
   }
 }
index bd3ba1c9a322e5cbadff9b1a613f66c40b45fea7..46877b24e621f8ff003887225b8a63844814dc0b 100644 (file)
@@ -1,6 +1,6 @@
 import { Request, Response, Router } from "express";
 import { maxHp, Player } from "../../../shared/player";
-import { authEndpoint } from '../../auth';
+import { authEndpoint, AuthRequest } from '../../auth';
 import { logger } from "../../lib/logger";
 import { loadPlayer, updatePlayer } from "../../player";
 import { getCityDetails, getService } from '../../map';
@@ -91,18 +91,11 @@ function getText(type: TextSegment, location: Location, city: City): string {
 
 }
 
-router.get('/city/services/city:services:healer/:location_id', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken']!.toString();
-  const player: Player = await loadPlayer(authToken)
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
+router.get('/city/services/city:services:healer/:location_id', authEndpoint, async (req: AuthRequest, res: Response) => {
   const service = await getService(parseInt(req.params.location_id));
   const city = await getCityDetails(service.city_id);
 
-  if(!service || service.city_id !== player.city_id) {
+  if(!service || service.city_id !== req.player.city_id) {
     logger.log(`Invalid location: [${req.params.location_id}]`);
     res.sendStatus(400);
   }
@@ -113,11 +106,11 @@ router.get('/city/services/city:services:healer/:location_id', authEndpoint, asy
   text.push(`<p>"${getText('intro', service, city)}"</p>`);
 
 
-  if(player.hp === maxHp(player.constitution, player.level)) {
+  if(req.player.hp === maxHp(req.player.constitution, req.player.level)) {
     text.push(`<p>You're already at full health?</p>`);
   }
   else {
-    if(player.gold <= (healCost * 2)) {
+    if(req.player.gold <= (healCost * 2)) {
       text.push(`<p>You don't seem to have too much money... I guess I can do it for free this time...</p>`);
       text.push(`<p><button type="button" hx-post="/city/services/city:services:healer:heal/${service.id}" hx-target="#explore">Heal for Free!</button></p>`);
     }
@@ -132,18 +125,11 @@ router.get('/city/services/city:services:healer/:location_id', authEndpoint, asy
 
 
 
-router.post('/city/services/city:services:healer:heal/:location_id', authEndpoint, async (req: Request, res: Response) => {
-  const authToken = req.headers['x-authtoken']!.toString();
-  const player: Player = await loadPlayer(authToken)
-  if(!player) {
-    logger.log(`Couldnt find player with id ${authToken}`);
-    return res.sendStatus(400);
-  }
-
+router.post('/city/services/city:services:healer:heal/:location_id', authEndpoint, async (req: AuthRequest, res: Response) => {
   const service = await getService(parseInt(req.params.location_id));
   const city = await getCityDetails(service.city_id);
 
-  if(!service || service.city_id !== player.city_id) {
+  if(!service || service.city_id !== req.player.city_id) {
     logger.log(`Invalid location: [${req.params.location_id}]`);
     res.sendStatus(400);
   }
@@ -151,21 +137,21 @@ router.post('/city/services/city:services:healer:heal/:location_id', authEndpoin
   const text: string[] = [];
   text.push(`<p><b>${service.name}</b></p>`);
 
-  const cost = player.gold <= (healCost * 2) ? 0 : healCost;
+  const cost = req.player.gold <= (healCost * 2) ? 0 : healCost;
 
-  if(player.gold < cost) {
+  if(req.player.gold < cost) {
     text.push(`<p>${getText('insufficient_money', service, city)}</p>`)
     res.send(`<div>${text.join("\n")}</div>`);
   }
   else {
-    player.hp = maxHp(player.constitution, player.level);
-    player.gold -= cost;
+    req.player.hp = maxHp(req.player.constitution, req.player.level);
+    req.player.gold -= cost;
 
-    await updatePlayer(player);
-    const inventory = await getEquippedItems(player.id);
+    await updatePlayer(req.player);
+    const inventory = await getEquippedItems(req.player.id);
 
     text.push(`<p>${getText('heal_successful', service, city)}</p>`);
     text.push('<p><button hx-get="/player/explore" hx-target="#explore">Back to Town</button></p>');
-    res.send(`<div>${text.join("\n")}</div>` + renderPlayerBar(player, inventory));
+    res.send(`<div>${text.join("\n")}</div>` + renderPlayerBar(req.player, inventory));
   }
 });
index fdd51b4c07b376230e7c7b8640c15cf8ecdf7117..b6ed6dcf276ca62095cf94a22da6a9e3927645ad 100644 (file)
@@ -23,8 +23,7 @@ export function renderRoundDetails(roundData: FightRound): string {
       html.push('<p><button hx-get="/player/explore" hx-target="#explore">Back to Town</button></p>');
     break;
     case 'in-progress':
-      // still in progress? 
-      console.log('in progress still');
+      // fight still in progress, so we don't send any final actions back
     break;
   }