mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 07:30:20 +00:00
Begin api-key functionality on backend
This commit is contained in:
+3
-2
@@ -27,7 +27,8 @@ import {
|
||||
password as passwordRouter,
|
||||
stripe as stripeRouter,
|
||||
integration as integrationRouter,
|
||||
integrationAuth as integrationAuthRouter
|
||||
integrationAuth as integrationAuthRouter,
|
||||
apiKey as apiKeyRouter
|
||||
} from './routes';
|
||||
import { getLogger } from './utils/logger';
|
||||
import { RouteNotFoundError } from './utils/errors';
|
||||
@@ -74,7 +75,7 @@ app.use('/api/v1/password', passwordRouter);
|
||||
app.use('/api/v1/stripe', stripeRouter);
|
||||
app.use('/api/v1/integration', integrationRouter);
|
||||
app.use('/api/v1/integration-auth', integrationAuthRouter);
|
||||
|
||||
app.use('/api/v1/api-key', apiKeyRouter);
|
||||
|
||||
//* Handle unrouted requests and respond with proper error message as well as status code
|
||||
app.use((req, res, next)=>{
|
||||
|
||||
@@ -74,3 +74,12 @@ export const createServiceToken = async (req: Request, res: Response) => {
|
||||
token
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* SERVICE_TOKEN: <JWT_SERVICE_TOKEN>,<PRIVATE_KEY_SERVICE_TOKEN>
|
||||
* - <JWT_SERVICE_TOKEN> authorizes the service token for "service token"-only endpoints.
|
||||
* - <PRIVATE_KEY_SERVICE_TOKEN> authorizes the service token to pull secrets via that endpoint.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
@@ -0,0 +1,63 @@
|
||||
import { Schema, model, Types } from 'mongoose';
|
||||
import { ENV_DEV, ENV_TESTING, ENV_STAGING, ENV_PROD } from '../variables';
|
||||
|
||||
// TODO: add scopes
|
||||
|
||||
export interface IAPIKey {
|
||||
name: string;
|
||||
workspace: string;
|
||||
environment: string;
|
||||
expiresAt: Date;
|
||||
prefix: string;
|
||||
apiKeyHash: string;
|
||||
encryptedKey: string;
|
||||
iv: string;
|
||||
tag: string;
|
||||
}
|
||||
|
||||
const apiKeySchema = new Schema<IAPIKey>(
|
||||
{
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
workspace: {
|
||||
type: String
|
||||
},
|
||||
environment: {
|
||||
type: String,
|
||||
enum: [ENV_DEV, ENV_TESTING, ENV_STAGING, ENV_PROD]
|
||||
},
|
||||
expiresAt: {
|
||||
type: Date
|
||||
},
|
||||
prefix: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
apiKeyHash: {
|
||||
type: String,
|
||||
unique: true,
|
||||
required: true
|
||||
},
|
||||
encryptedKey: {
|
||||
type: String,
|
||||
select: true
|
||||
},
|
||||
iv: {
|
||||
type: String,
|
||||
select: true
|
||||
},
|
||||
tag: {
|
||||
type: String,
|
||||
select: true
|
||||
}
|
||||
},
|
||||
{
|
||||
timestamps: true
|
||||
}
|
||||
);
|
||||
|
||||
const APIKey = model<IAPIKey>('APIKey', apiKeySchema);
|
||||
|
||||
export default APIKey;
|
||||
@@ -14,6 +14,7 @@ import Token, { IToken } from './token';
|
||||
import User, { IUser } from './user';
|
||||
import UserAction, { IUserAction } from './userAction';
|
||||
import Workspace, { IWorkspace } from './workspace';
|
||||
import APIKey, { IAPIKey } from './apiKey';
|
||||
|
||||
export {
|
||||
BackupPrivateKey,
|
||||
@@ -47,5 +48,7 @@ export {
|
||||
UserAction,
|
||||
IUserAction,
|
||||
Workspace,
|
||||
IWorkspace
|
||||
IWorkspace,
|
||||
APIKey,
|
||||
IAPIKey,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import express from 'express';
|
||||
const router = express.Router();
|
||||
import {
|
||||
requireAuth
|
||||
} from '../middleware';
|
||||
import {
|
||||
APIKey
|
||||
} from '../models';
|
||||
import { body } from 'express-validator';
|
||||
import crypto from 'crypto';
|
||||
import bcrypt from 'bcrypt';
|
||||
// import * as bcrypt from 'bcrypt';
|
||||
// const bcrypt = require('bcrypt');
|
||||
import * as Sentry from '@sentry/node';
|
||||
|
||||
// POST /api/v1/api-key
|
||||
router.post(
|
||||
'/',
|
||||
requireAuth,
|
||||
body('name').exists().trim(),
|
||||
body('workspace'),
|
||||
body('environment'),
|
||||
body('encryptedKey'),
|
||||
body('iv'),
|
||||
body('tag'),
|
||||
body('expiresAt'),
|
||||
async (req, res) => {
|
||||
let savedAPIKey;
|
||||
try {
|
||||
const {
|
||||
name,
|
||||
workspace,
|
||||
environment,
|
||||
encryptedKey,
|
||||
iv,
|
||||
tag,
|
||||
expiresAt
|
||||
} = req.body;
|
||||
|
||||
// api-key: 38 characters
|
||||
// 6-char: prefix
|
||||
// 32-char: remaining
|
||||
const apiKey = crypto.randomBytes(19).toString('hex');
|
||||
const saltRounds = 10; // config?
|
||||
const apiKeyHash = await bcrypt.hash(apiKey, saltRounds);
|
||||
|
||||
savedAPIKey = await new APIKey({
|
||||
name,
|
||||
workspace,
|
||||
environment,
|
||||
expiresAt,
|
||||
prefix: apiKey.substring(0, 6),
|
||||
apiKeyHash,
|
||||
encryptedKey,
|
||||
iv,
|
||||
tag
|
||||
}).save();
|
||||
|
||||
// 1. generate api key
|
||||
// 2. hash api key with bcrypt
|
||||
// 3. store hash and api key info in db
|
||||
// 4. return api key
|
||||
|
||||
} catch (err) {
|
||||
Sentry.setUser({ email: req.user.email });
|
||||
Sentry.captureException(err);
|
||||
return res.status(400).send({
|
||||
message: 'xxx'
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(200).send({
|
||||
apiKey: savedAPIKey
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// INFISICAL TOKEN = <API_KEY>.<KEY>
|
||||
|
||||
export default router;
|
||||
@@ -15,6 +15,7 @@ import password from './password';
|
||||
import stripe from './stripe';
|
||||
import integration from './integration';
|
||||
import integrationAuth from './integrationAuth';
|
||||
import apiKey from './apiKey';
|
||||
|
||||
export {
|
||||
signup,
|
||||
@@ -33,5 +34,6 @@ export {
|
||||
password,
|
||||
stripe,
|
||||
integration,
|
||||
integrationAuth
|
||||
integrationAuth,
|
||||
apiKey
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ import { body } from 'express-validator';
|
||||
import { ADMIN, MEMBER, GRANTED } from '../variables';
|
||||
import { serviceTokenController } from '../controllers';
|
||||
|
||||
// TODO: revoke service token
|
||||
// Note to devs: service-token to be deprecated in favor of api-key
|
||||
|
||||
router.get(
|
||||
'/',
|
||||
|
||||
Reference in New Issue
Block a user