All files / server/controllers/user.controller apiKey.js

86% Statements 43/50
72.22% Branches 13/18
100% Functions 15/15
85.71% Lines 42/49

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104                  1x 1x 1x     1x 1x           3x   2x 2x     3x 3x 1x 1x     2x 1x 1x     1x   1x   1x 1x         1x   1x 1x   1x         1x 1x             3x   2x 2x     3x 3x         3x 1x 1x     2x 2x 1x 1x     1x   1x 1x         1x 1x          
import crypto from 'crypto';
 
import User from '../../models/user';
 
/**
 * Generates a unique token to be used as a Personal Access Token
 * @returns Promise<String> A promise that resolves to the token, or an Error
 */
function generateApiKey() {
  return new Promise((resolve, reject) => {
    crypto.randomBytes(20, (err, buf) => {
      Iif (err) {
        reject(err);
      }
      const key = buf.toString('hex');
      resolve(Buffer.from(key).toString('base64'));
    });
  });
}
 
export function createApiKey(req, res) {
  return new Promise((resolve, reject) => {
    function sendFailure(code, error) {
      res.status(code).json({ error });
      resolve();
    }
 
    User.findById(req.user.id, async (err, user) => {
      if (!user) {
        sendFailure(404, 'User not found');
        return;
      }
 
      if (!req.body.label) {
        sendFailure(400, 'Expected field \'label\' was not present in request body');
        return;
      }
 
      const keyToBeHashed = await generateApiKey();
 
      const addedApiKeyIndex = user.apiKeys.push({ label: req.body.label, hashedKey: keyToBeHashed });
 
      user.save((saveErr) => {
        Iif (saveErr) {
          sendFailure(500, saveErr);
          return;
        }
 
        const apiKeys = user.apiKeys
          .map((apiKey, index) => {
            const fields = apiKey.toObject();
            const shouldIncludeToken = index === addedApiKeyIndex - 1;
 
            return shouldIncludeToken ?
              { ...fields, token: keyToBeHashed } :
              fields;
          });
 
        res.json({ apiKeys });
        resolve();
      });
    });
  });
}
 
export function removeApiKey(req, res) {
  return new Promise((resolve, reject) => {
    function sendFailure(code, error) {
      res.status(code).json({ error });
      resolve();
    }
 
    User.findById(req.user.id, (err, user) => {
      Iif (err) {
        sendFailure(500, err);
        return;
      }
 
      if (!user) {
        sendFailure(404, 'User not found');
        return;
      }
 
      const keyToDelete = user.apiKeys.find(key => key.id === req.params.keyId);
      if (!keyToDelete) {
        sendFailure(404, 'Key does not exist for user');
        return;
      }
 
      user.apiKeys.pull({ _id: req.params.keyId });
 
      user.save((saveErr) => {
        Iif (saveErr) {
          sendFailure(500, saveErr);
          return;
        }
 
        res.status(200).json({ apiKeys: user.apiKeys });
        resolve();
      });
    });
  });
}