mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Merge branch 'main' of github.com:atimapreandrew/infisical
This commit is contained in:
@@ -1,72 +0,0 @@
|
||||
import { Request, Response } from "express";
|
||||
import crypto from "crypto";
|
||||
import bcrypt from "bcrypt";
|
||||
import { APIKeyData } from "../../models";
|
||||
import { getSaltRounds } from "../../config";
|
||||
|
||||
/**
|
||||
* Return API key data for user with id [req.user_id]
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const getAPIKeyData = async (req: Request, res: Response) => {
|
||||
const apiKeyData = await APIKeyData.find({
|
||||
user: req.user._id,
|
||||
});
|
||||
|
||||
return res.status(200).send({
|
||||
apiKeyData,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new API key data for user with id [req.user._id]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const createAPIKeyData = async (req: Request, res: Response) => {
|
||||
const { name, expiresIn } = req.body;
|
||||
|
||||
const secret = crypto.randomBytes(16).toString("hex");
|
||||
const secretHash = await bcrypt.hash(secret, await getSaltRounds());
|
||||
|
||||
const expiresAt = new Date();
|
||||
expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn);
|
||||
|
||||
let apiKeyData = await new APIKeyData({
|
||||
name,
|
||||
lastUsed: new Date(),
|
||||
expiresAt,
|
||||
user: req.user._id,
|
||||
secretHash,
|
||||
}).save();
|
||||
|
||||
// return api key data without sensitive data
|
||||
// FIX: fix this any
|
||||
apiKeyData = (await APIKeyData.findById(apiKeyData._id)) as any;
|
||||
|
||||
if (!apiKeyData) throw new Error("Failed to find API key data");
|
||||
|
||||
const apiKey = `ak.${apiKeyData._id.toString()}.${secret}`;
|
||||
|
||||
return res.status(200).send({
|
||||
apiKey,
|
||||
apiKeyData,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete API key data with id [apiKeyDataId].
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const deleteAPIKeyData = async (req: Request, res: Response) => {
|
||||
const { apiKeyDataId } = req.params;
|
||||
const apiKeyData = await APIKeyData.findByIdAndDelete(apiKeyDataId);
|
||||
|
||||
return res.status(200).send({
|
||||
apiKeyData,
|
||||
});
|
||||
};
|
||||
@@ -4,7 +4,6 @@ import * as usersController from "./usersController";
|
||||
import * as organizationsController from "./organizationsController";
|
||||
import * as workspaceController from "./workspaceController";
|
||||
import * as serviceTokenDataController from "./serviceTokenDataController";
|
||||
import * as apiKeyDataController from "./apiKeyDataController";
|
||||
import * as secretController from "./secretController";
|
||||
import * as secretsController from "./secretsController";
|
||||
import * as serviceAccountsController from "./serviceAccountsController";
|
||||
@@ -18,7 +17,6 @@ export {
|
||||
organizationsController,
|
||||
workspaceController,
|
||||
serviceTokenDataController,
|
||||
apiKeyDataController,
|
||||
secretController,
|
||||
secretsController,
|
||||
serviceAccountsController,
|
||||
|
||||
@@ -15,7 +15,7 @@ export const createWorkspaceTag = async (req: Request, res: Response) => {
|
||||
user: new Types.ObjectId(req.user._id),
|
||||
};
|
||||
|
||||
const createdTag = await new Tag(tagToCreate);
|
||||
const createdTag = await new Tag(tagToCreate).save();
|
||||
|
||||
res.json(createdTag);
|
||||
};
|
||||
@@ -48,7 +48,11 @@ export const deleteWorkspaceTag = async (req: Request, res: Response) => {
|
||||
|
||||
export const getWorkspaceTags = async (req: Request, res: Response) => {
|
||||
const { workspaceId } = req.params;
|
||||
const workspaceTags = await Tag.find({ workspace: workspaceId });
|
||||
|
||||
const workspaceTags = await Tag.find({
|
||||
workspace: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
|
||||
return res.json({
|
||||
workspaceTags
|
||||
});
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import { Request, Response } from "express";
|
||||
import { Types } from "mongoose";
|
||||
import crypto from "crypto";
|
||||
import bcrypt from "bcrypt";
|
||||
import {
|
||||
MembershipOrg,
|
||||
User,
|
||||
APIKeyData,
|
||||
TokenVersion
|
||||
} from "../../models";
|
||||
import { getSaltRounds } from "../../config";
|
||||
|
||||
/**
|
||||
* Return the current user.
|
||||
@@ -117,3 +123,106 @@ export const getMyOrganizations = async (req: Request, res: Response) => {
|
||||
organizations,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return API keys belonging to current user.
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const getMyAPIKeys = async (req: Request, res: Response) => {
|
||||
const apiKeyData = await APIKeyData.find({
|
||||
user: req.user._id,
|
||||
});
|
||||
|
||||
return res.status(200).send(apiKeyData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new API key for current user.
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const createAPIKey = async (req: Request, res: Response) => {
|
||||
const { name, expiresIn } = req.body;
|
||||
|
||||
const secret = crypto.randomBytes(16).toString("hex");
|
||||
const secretHash = await bcrypt.hash(secret, await getSaltRounds());
|
||||
|
||||
const expiresAt = new Date();
|
||||
expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn);
|
||||
|
||||
let apiKeyData = await new APIKeyData({
|
||||
name,
|
||||
lastUsed: new Date(),
|
||||
expiresAt,
|
||||
user: req.user._id,
|
||||
secretHash,
|
||||
}).save();
|
||||
|
||||
// return api key data without sensitive data
|
||||
apiKeyData = (await APIKeyData.findById(apiKeyData._id)) as any;
|
||||
|
||||
if (!apiKeyData) throw new Error("Failed to find API key data");
|
||||
|
||||
const apiKey = `ak.${apiKeyData._id.toString()}.${secret}`;
|
||||
|
||||
return res.status(200).send({
|
||||
apiKey,
|
||||
apiKeyData,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete API key with id [apiKeyDataId] belonging to current user
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const deleteAPIKey = async (req: Request, res: Response) => {
|
||||
const { apiKeyDataId } = req.params;
|
||||
|
||||
const apiKeyData = await APIKeyData.findOneAndDelete({
|
||||
_id: new Types.ObjectId(apiKeyDataId),
|
||||
user: req.user._id
|
||||
});
|
||||
|
||||
return res.status(200).send({
|
||||
apiKeyData
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return active sessions (TokenVersion) belonging to user
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const getMySessions = async (req: Request, res: Response) => {
|
||||
const tokenVersions = await TokenVersion.find({
|
||||
user: req.user._id
|
||||
});
|
||||
|
||||
return res.status(200).send(tokenVersions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke all active sessions belong to user
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const deleteMySessions = async (req: Request, res: Response) => {
|
||||
await TokenVersion.updateMany({
|
||||
user: req.user._id,
|
||||
}, {
|
||||
$inc: {
|
||||
refreshVersion: 1,
|
||||
accessVersion: 1,
|
||||
},
|
||||
});
|
||||
|
||||
return res.status(200).send({
|
||||
message: "Successfully revoked all sessions"
|
||||
});
|
||||
}
|
||||
@@ -54,23 +54,20 @@ export const getSecretVersions = async (req: Request, res: Response) => {
|
||||
}
|
||||
}
|
||||
*/
|
||||
const { secretId, workspaceId, environment, folderId } = req.params;
|
||||
const { secretId } = req.params;
|
||||
|
||||
const offset: number = parseInt(req.query.offset as string);
|
||||
const limit: number = parseInt(req.query.limit as string);
|
||||
|
||||
const secretVersions = await SecretVersion.find({
|
||||
secret: secretId,
|
||||
workspace: workspaceId,
|
||||
environment,
|
||||
folder: folderId,
|
||||
secret: secretId
|
||||
})
|
||||
.sort({ createdAt: -1 })
|
||||
.skip(offset)
|
||||
.limit(limit);
|
||||
|
||||
return res.status(200).send({
|
||||
secretVersions,
|
||||
secretVersions
|
||||
});
|
||||
};
|
||||
|
||||
@@ -135,7 +132,7 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => {
|
||||
// validate secret version
|
||||
const oldSecretVersion = await SecretVersion.findOne({
|
||||
secret: secretId,
|
||||
version,
|
||||
version
|
||||
}).select("+secretBlindIndex");
|
||||
|
||||
if (!oldSecretVersion) throw new Error("Failed to find secret version");
|
||||
@@ -154,7 +151,7 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => {
|
||||
secretValueTag,
|
||||
algorithm,
|
||||
folder,
|
||||
keyEncoding,
|
||||
keyEncoding
|
||||
} = oldSecretVersion;
|
||||
|
||||
// update secret
|
||||
@@ -162,7 +159,7 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => {
|
||||
secretId,
|
||||
{
|
||||
$inc: {
|
||||
version: 1,
|
||||
version: 1
|
||||
},
|
||||
workspace,
|
||||
type,
|
||||
@@ -177,10 +174,10 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => {
|
||||
secretValueTag,
|
||||
folderId: folder,
|
||||
algorithm,
|
||||
keyEncoding,
|
||||
keyEncoding
|
||||
},
|
||||
{
|
||||
new: true,
|
||||
new: true
|
||||
}
|
||||
);
|
||||
|
||||
@@ -204,17 +201,17 @@ export const rollbackSecretVersion = async (req: Request, res: Response) => {
|
||||
secretValueTag,
|
||||
folder,
|
||||
algorithm,
|
||||
keyEncoding,
|
||||
keyEncoding
|
||||
}).save();
|
||||
|
||||
// take secret snapshot
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
workspaceId: secret.workspace,
|
||||
environment,
|
||||
folderId: folder,
|
||||
folderId: folder
|
||||
});
|
||||
|
||||
return res.status(200).send({
|
||||
secret,
|
||||
secret
|
||||
});
|
||||
};
|
||||
|
||||
@@ -51,7 +51,6 @@ import {
|
||||
secrets as v2SecretsRouter,
|
||||
serviceTokenData as v2ServiceTokenDataRouter,
|
||||
serviceAccounts as v2ServiceAccountsRouter,
|
||||
apiKeyData as v2APIKeyDataRouter,
|
||||
environment as v2EnvironmentRouter,
|
||||
tags as v2TagsRouter,
|
||||
} from "./routes/v2";
|
||||
@@ -138,7 +137,6 @@ const main = async () => {
|
||||
app.use("/api/v2/secrets", v2SecretsRouter); // note: in the process of moving to v3/secrets
|
||||
app.use("/api/v2/service-token", v2ServiceTokenDataRouter);
|
||||
app.use("/api/v2/service-accounts", v2ServiceAccountsRouter); // new
|
||||
app.use("/api/v2/api-key", v2APIKeyDataRouter);
|
||||
|
||||
// v3 routes (experimental)
|
||||
app.use("/api/v3/auth", v3AuthRouter);
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import express from "express";
|
||||
const router = express.Router();
|
||||
import { body, param } from "express-validator";
|
||||
import {
|
||||
requireAuth,
|
||||
validateRequest,
|
||||
} from "../../middleware";
|
||||
import { apiKeyDataController } from "../../controllers/v2";
|
||||
import {
|
||||
AUTH_MODE_JWT,
|
||||
} from "../../variables";
|
||||
|
||||
router.get(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
apiKeyDataController.getAPIKeyData
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
body("name").exists().trim(),
|
||||
body("expiresIn"), // measured in ms
|
||||
validateRequest,
|
||||
apiKeyDataController.createAPIKeyData
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/:apiKeyDataId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
param("apiKeyDataId").exists().trim(),
|
||||
validateRequest,
|
||||
apiKeyDataController.deleteAPIKeyData
|
||||
);
|
||||
|
||||
export default router;
|
||||
@@ -7,7 +7,6 @@ import secret from "./secret"; // deprecated
|
||||
import secrets from "./secrets";
|
||||
import serviceTokenData from "./serviceTokenData";
|
||||
import serviceAccounts from "./serviceAccounts";
|
||||
import apiKeyData from "./apiKeyData";
|
||||
import environment from "./environment"
|
||||
import tags from "./tags"
|
||||
|
||||
@@ -21,7 +20,6 @@ export {
|
||||
secrets,
|
||||
serviceTokenData,
|
||||
serviceAccounts,
|
||||
apiKeyData,
|
||||
environment,
|
||||
tags,
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
requireAuth,
|
||||
validateRequest,
|
||||
} from "../../middleware";
|
||||
import { body } from "express-validator";
|
||||
import { body, param } from "express-validator";
|
||||
import { usersController } from "../../controllers/v2";
|
||||
import {
|
||||
AUTH_MODE_API_KEY,
|
||||
@@ -37,4 +37,49 @@ router.get(
|
||||
usersController.getMyOrganizations
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/me/api-keys",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
usersController.getMyAPIKeys
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/me/api-keys",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
body("name").exists().isString().trim(),
|
||||
body("expiresIn").isNumeric(),
|
||||
validateRequest,
|
||||
usersController.createAPIKey
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/me/api-keys/:apiKeyDataId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
param("apiKeyDataId").exists().trim(),
|
||||
validateRequest,
|
||||
usersController.deleteAPIKey
|
||||
);
|
||||
|
||||
router.get( // new
|
||||
"/me/sessions",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
usersController.getMySessions
|
||||
);
|
||||
|
||||
router.delete( // new
|
||||
"/me/sessions",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AUTH_MODE_JWT],
|
||||
}),
|
||||
usersController.deleteMySessions
|
||||
);
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user