mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00: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 workspaceController from './workspaceController';
|
||||||
import * as serviceTokenDataController from './serviceTokenDataController';
|
import * as serviceTokenDataController from './serviceTokenDataController';
|
||||||
|
import * as apiKeyDataController from './apiKeyDataController';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
workspaceController,
|
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 User, { IUser } from './user';
|
||||||
import UserAction, { IUserAction } from './userAction';
|
import UserAction, { IUserAction } from './userAction';
|
||||||
import Workspace, { IWorkspace } from './workspace';
|
import Workspace, { IWorkspace } from './workspace';
|
||||||
import ServiceTokenData, { IServiceTokenData } from './serviceTokenData ';
|
import ServiceTokenData, { IServiceTokenData } from './serviceTokenData';
|
||||||
|
import APIKeyData, { IAPIKeyData } from './apiKeyData';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
BackupPrivateKey,
|
BackupPrivateKey,
|
||||||
@@ -50,5 +51,7 @@ export {
|
|||||||
Workspace,
|
Workspace,
|
||||||
IWorkspace,
|
IWorkspace,
|
||||||
ServiceTokenData,
|
ServiceTokenData,
|
||||||
IServiceTokenData
|
IServiceTokenData,
|
||||||
|
APIKeyData,
|
||||||
|
IAPIKeyData
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Schema, model, Types } from 'mongoose';
|
import { Schema, model, Types } from 'mongoose';
|
||||||
import { ENV_DEV, ENV_TESTING, ENV_STAGING, ENV_PROD } from '../variables';
|
|
||||||
|
|
||||||
export interface IServiceTokenData {
|
export interface IServiceTokenData {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -38,7 +37,6 @@ const serviceTokenDataSchema = new Schema<IServiceTokenData>(
|
|||||||
},
|
},
|
||||||
secretHash: {
|
secretHash: {
|
||||||
type: String,
|
type: String,
|
||||||
unique: true,
|
|
||||||
required: true,
|
required: true,
|
||||||
select: false
|
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 secret from './secret';
|
||||||
import workspace from './workspace';
|
import workspace from './workspace';
|
||||||
import serviceTokenData from './serviceTokenData';
|
import serviceTokenData from './serviceTokenData';
|
||||||
|
import apiKeyData from './apiKeyData';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
secret,
|
secret,
|
||||||
workspace,
|
workspace,
|
||||||
serviceTokenData
|
serviceTokenData,
|
||||||
|
apiKeyData
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user