Skip to content

Commit

Permalink
Begin API Key functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
dangtony98 committed Jan 4, 2023
1 parent 212ca72 commit ff0b053
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 6 deletions.
54 changes: 54 additions & 0 deletions backend/src/controllers/v2/apiKeyDataController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Request, Response } from 'express';
import * as Sentry from '@sentry/node';
import crypto from 'crypto';
import bcrypt from 'bcrypt';
import {
APIKeyData
} from '../../models';
import {
SALT_ROUNDS
} from '../../config';

/**
* Create new API key for user with id [req.user._id]
* @param req
* @param res
*/
export const createAPIKey = async (req: Request, res: Response) => {
let apiKey, apiKeyData;
try {
const { name, expiresIn } = req.body;

const secret = crypto.randomBytes(16).toString('hex');
const secretHash = await bcrypt.hash(secret, SALT_ROUNDS);

const expiresAt = new Date();
expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn);

apiKeyData = await new APIKeyData({
name,
expiresAt,
user: req.user._id,
secretHash
});

// return api key data without sensitive data
apiKeyData = await APIKeyData.findById(apiKeyData._id);

if (!apiKeyData) throw new Error('Failed to find API key data');

apiKey = `ak.${apiKeyData._id.toString()}.${secret}`;

} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to create service token data'
});
}

return res.status(200).send({
apiKey,
apiKeyData
});
}
4 changes: 3 additions & 1 deletion backend/src/controllers/v2/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import * as workspaceController from './workspaceController';
import * as serviceTokenDataController from './serviceTokenDataController';
import * as apiKeyDataController from './apiKeyDataController';

export {
workspaceController,
serviceTokenDataController
serviceTokenDataController,
apiKeyDataController
}
37 changes: 37 additions & 0 deletions backend/src/models/apiKeyData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Schema, model, Types } from 'mongoose';

export interface IAPIKeyData {
name: string;
user: Types.ObjectId;
expiresAt: Date;
secretHash: string;
}

const apiKeyDataSchema = new Schema<IAPIKeyData>(
{
name: {
type: String,
required: true
},
user: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
expiresAt: {
type: Date
},
secretHash: {
type: String,
required: true,
select: false
}
},
{
timestamps: true
}
);

const APIKeyData = model<IAPIKeyData>('APIKeyData', apiKeyDataSchema);

export default APIKeyData;
7 changes: 5 additions & 2 deletions backend/src/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import Token, { IToken } from './token';
import User, { IUser } from './user';
import UserAction, { IUserAction } from './userAction';
import Workspace, { IWorkspace } from './workspace';
import ServiceTokenData, { IServiceTokenData } from './serviceTokenData ';
import ServiceTokenData, { IServiceTokenData } from './serviceTokenData';
import APIKeyData, { IAPIKeyData } from './apiKeyData';

export {
BackupPrivateKey,
Expand Down Expand Up @@ -50,5 +51,7 @@ export {
Workspace,
IWorkspace,
ServiceTokenData,
IServiceTokenData
IServiceTokenData,
APIKeyData,
IAPIKeyData
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Schema, model, Types } from 'mongoose';
import { ENV_DEV, ENV_TESTING, ENV_STAGING, ENV_PROD } from '../variables';

export interface IServiceTokenData {
name: string;
Expand Down Expand Up @@ -38,7 +37,6 @@ const serviceTokenDataSchema = new Schema<IServiceTokenData>(
},
secretHash: {
type: String,
unique: true,
required: true,
select: false
},
Expand Down
21 changes: 21 additions & 0 deletions backend/src/routes/v2/apiKeyData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import express from 'express';
const router = express.Router();
import {
requireAuth,
validateRequest
} from '../../middleware';
import { body } from 'express-validator';
import { apiKeyDataController } from '../../controllers/v2';

router.post(
'/',
requireAuth({
acceptedAuthModes: ['jwt']
}),
body('name').exists().trim(),
body('expiresIn'), // measured in ms
validateRequest,
apiKeyDataController.createAPIKey
);

export default router;
4 changes: 3 additions & 1 deletion backend/src/routes/v2/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import secret from './secret';
import workspace from './workspace';
import serviceTokenData from './serviceTokenData';
import apiKeyData from './apiKeyData';

export {
secret,
workspace,
serviceTokenData
serviceTokenData,
apiKeyData
}

0 comments on commit ff0b053

Please sign in to comment.