mirror of
https://github.com/Infisical/infisical.git
synced 2026-05-02 03:02:03 -04:00
Begin API Key functionality
This commit is contained in:
54
backend/src/controllers/v2/apiKeyDataController.ts
Normal file
54
backend/src/controllers/v2/apiKeyDataController.ts
Normal file
@@ -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
|
||||
});
|
||||
}
|
||||
@@ -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
backend/src/models/apiKeyData.ts
Normal file
37
backend/src/models/apiKeyData.ts
Normal file
@@ -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;
|
||||
@@ -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,
|
||||
@@ -50,5 +51,7 @@ export {
|
||||
Workspace,
|
||||
IWorkspace,
|
||||
ServiceTokenData,
|
||||
IServiceTokenData
|
||||
IServiceTokenData,
|
||||
APIKeyData,
|
||||
IAPIKeyData
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
@@ -38,7 +37,6 @@ const serviceTokenDataSchema = new Schema<IServiceTokenData>(
|
||||
},
|
||||
secretHash: {
|
||||
type: String,
|
||||
unique: true,
|
||||
required: true,
|
||||
select: false
|
||||
},
|
||||
21
backend/src/routes/v2/apiKeyData.ts
Normal file
21
backend/src/routes/v2/apiKeyData.ts
Normal file
@@ -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;
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user