mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 21:27:31 +00:00
Merge remote-tracking branch 'origin' into org-settings
This commit is contained in:
@@ -136,7 +136,7 @@ Not sure where to get started? You can:
|
|||||||
- [Slack](https://join.slack.com/t/infisical-users/shared_invite/zt-1wehzfnzn-1aMo5JcGENJiNAC2SD8Jlg) for discussion with the community and Infisical team.
|
- [Slack](https://join.slack.com/t/infisical-users/shared_invite/zt-1wehzfnzn-1aMo5JcGENJiNAC2SD8Jlg) for discussion with the community and Infisical team.
|
||||||
- [GitHub](https://github.com/Infisical/infisical) for code, issues, and pull requests
|
- [GitHub](https://github.com/Infisical/infisical) for code, issues, and pull requests
|
||||||
- [Twitter](https://twitter.com/infisical) for fast news
|
- [Twitter](https://twitter.com/infisical) for fast news
|
||||||
- [YouTube](https://www.youtube.com/@infisical5306) for videos on secret management
|
- [YouTube](https://www.youtube.com/@infisical_od) for videos on secret management
|
||||||
- [Blog](https://infisical.com/blog) for secret management insights, articles, tutorials, and updates
|
- [Blog](https://infisical.com/blog) for secret management insights, articles, tutorials, and updates
|
||||||
- [Roadmap](https://www.notion.so/infisical/be2d2585a6694e40889b03aef96ea36b?v=5b19a8127d1a4060b54769567a8785fa) for planned features
|
- [Roadmap](https://www.notion.so/infisical/be2d2585a6694e40889b03aef96ea36b?v=5b19a8127d1a4060b54769567a8785fa) for planned features
|
||||||
|
|
||||||
|
|||||||
Generated
-25
@@ -17,13 +17,11 @@
|
|||||||
"@types/crypto-js": "^4.1.1",
|
"@types/crypto-js": "^4.1.1",
|
||||||
"@types/libsodium-wrappers": "^0.7.10",
|
"@types/libsodium-wrappers": "^0.7.10",
|
||||||
"argon2": "^0.30.3",
|
"argon2": "^0.30.3",
|
||||||
"await-to-js": "^3.0.0",
|
|
||||||
"aws-sdk": "^2.1364.0",
|
"aws-sdk": "^2.1364.0",
|
||||||
"axios": "^1.3.5",
|
"axios": "^1.3.5",
|
||||||
"axios-retry": "^3.4.0",
|
"axios-retry": "^3.4.0",
|
||||||
"bcrypt": "^5.1.0",
|
"bcrypt": "^5.1.0",
|
||||||
"bigint-conversion": "^2.4.0",
|
"bigint-conversion": "^2.4.0",
|
||||||
"builder-pattern": "^2.2.0",
|
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
@@ -3787,14 +3785,6 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/await-to-js": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/aws-sdk": {
|
"node_modules/aws-sdk": {
|
||||||
"version": "2.1386.0",
|
"version": "2.1386.0",
|
||||||
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1386.0.tgz",
|
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1386.0.tgz",
|
||||||
@@ -4217,11 +4207,6 @@
|
|||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/builder-pattern": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/builder-pattern/-/builder-pattern-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-cES3qdeBzA4QyJi7rV/l/kAhIFX6AKo3vK66ZPXLNpjcQWCS8sjLKscly8imlfW2YPTo/hquMRMnaWpZ80Kj+g=="
|
|
||||||
},
|
|
||||||
"node_modules/bytes": {
|
"node_modules/bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
@@ -15393,11 +15378,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
|
||||||
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
|
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
|
||||||
},
|
},
|
||||||
"await-to-js": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g=="
|
|
||||||
},
|
|
||||||
"aws-sdk": {
|
"aws-sdk": {
|
||||||
"version": "2.1386.0",
|
"version": "2.1386.0",
|
||||||
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1386.0.tgz",
|
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1386.0.tgz",
|
||||||
@@ -15724,11 +15704,6 @@
|
|||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"builder-pattern": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/builder-pattern/-/builder-pattern-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-cES3qdeBzA4QyJi7rV/l/kAhIFX6AKo3vK66ZPXLNpjcQWCS8sjLKscly8imlfW2YPTo/hquMRMnaWpZ80Kj+g=="
|
|
||||||
},
|
|
||||||
"bytes": {
|
"bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
|
|||||||
@@ -8,13 +8,11 @@
|
|||||||
"@types/crypto-js": "^4.1.1",
|
"@types/crypto-js": "^4.1.1",
|
||||||
"@types/libsodium-wrappers": "^0.7.10",
|
"@types/libsodium-wrappers": "^0.7.10",
|
||||||
"argon2": "^0.30.3",
|
"argon2": "^0.30.3",
|
||||||
"await-to-js": "^3.0.0",
|
|
||||||
"aws-sdk": "^2.1364.0",
|
"aws-sdk": "^2.1364.0",
|
||||||
"axios": "^1.3.5",
|
"axios": "^1.3.5",
|
||||||
"axios-retry": "^3.4.0",
|
"axios-retry": "^3.4.0",
|
||||||
"bcrypt": "^5.1.0",
|
"bcrypt": "^5.1.0",
|
||||||
"bigint-conversion": "^2.4.0",
|
"bigint-conversion": "^2.4.0",
|
||||||
"builder-pattern": "^2.2.0",
|
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import to from "await-to-js";
|
|
||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
import mongoose, { Types } from "mongoose";
|
import mongoose, { Types } from "mongoose";
|
||||||
import Secret, { ISecret } from "../../models/secret";
|
import Secret, { ISecret } from "../../models/secret";
|
||||||
@@ -56,10 +55,7 @@ export const createSecret = async (req: Request, res: Response) => {
|
|||||||
keyEncoding: ENCODING_SCHEME_UTF8
|
keyEncoding: ENCODING_SCHEME_UTF8
|
||||||
};
|
};
|
||||||
|
|
||||||
const [error, secret] = await to(Secret.create(sanitizedSecret).then());
|
const secret = await new Secret(sanitizedSecret).save();
|
||||||
if (error instanceof ValidationError) {
|
|
||||||
throw RouteValidationError({ message: error.message, stack: error.stack });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (postHogClient) {
|
if (postHogClient) {
|
||||||
postHogClient.capture({
|
postHogClient.capture({
|
||||||
@@ -81,7 +77,7 @@ export const createSecret = async (req: Request, res: Response) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create many secrets for workspace wiht id [workspaceId] and environment [environment]
|
* Create many secrets for workspace with id [workspaceId] and environment [environment]
|
||||||
* @param req
|
* @param req
|
||||||
* @param res
|
* @param res
|
||||||
*/
|
*/
|
||||||
@@ -116,20 +112,7 @@ export const createSecrets = async (req: Request, res: Response) => {
|
|||||||
sanitizedSecretesToCreate.push(safeUpdateFields);
|
sanitizedSecretesToCreate.push(safeUpdateFields);
|
||||||
});
|
});
|
||||||
|
|
||||||
const [bulkCreateError, secrets] = await to(Secret.insertMany(sanitizedSecretesToCreate).then());
|
const secrets = await Secret.insertMany(sanitizedSecretesToCreate);
|
||||||
if (bulkCreateError) {
|
|
||||||
if (bulkCreateError instanceof ValidationError) {
|
|
||||||
throw RouteValidationError({
|
|
||||||
message: bulkCreateError.message,
|
|
||||||
stack: bulkCreateError.stack
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
throw InternalServerError({
|
|
||||||
message: "Unable to process your batch create request. Please try again",
|
|
||||||
stack: bulkCreateError.stack
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (postHogClient) {
|
if (postHogClient) {
|
||||||
postHogClient.capture({
|
postHogClient.capture({
|
||||||
@@ -160,14 +143,7 @@ export const deleteSecrets = async (req: Request, res: Response) => {
|
|||||||
const { workspaceId, environmentName } = req.params;
|
const { workspaceId, environmentName } = req.params;
|
||||||
const secretIdsToDelete: string[] = req.body.secretIds;
|
const secretIdsToDelete: string[] = req.body.secretIds;
|
||||||
|
|
||||||
const [secretIdsUserCanDeleteError, secretIdsUserCanDelete] = await to(
|
const secretIdsUserCanDelete = await Secret.find({ workspace: workspaceId, environment: environmentName }, { _id: 1 });
|
||||||
Secret.find({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then()
|
|
||||||
);
|
|
||||||
if (secretIdsUserCanDeleteError) {
|
|
||||||
throw InternalServerError({
|
|
||||||
message: `Unable to fetch secrets you own: [error=${secretIdsUserCanDeleteError.message}]`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const secretsUserCanDeleteSet: Set<string> = new Set(
|
const secretsUserCanDeleteSet: Set<string> = new Set(
|
||||||
secretIdsUserCanDelete.map((objectId) => objectId._id.toString())
|
secretIdsUserCanDelete.map((objectId) => objectId._id.toString())
|
||||||
@@ -189,16 +165,7 @@ export const deleteSecrets = async (req: Request, res: Response) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const [bulkDeleteError] = await to(Secret.bulkWrite(deleteOperationsToPerform).then());
|
await Secret.bulkWrite(deleteOperationsToPerform);
|
||||||
if (bulkDeleteError) {
|
|
||||||
if (bulkDeleteError instanceof ValidationError) {
|
|
||||||
throw RouteValidationError({
|
|
||||||
message: "Unable to apply modifications, please try again",
|
|
||||||
stack: bulkDeleteError.stack
|
|
||||||
});
|
|
||||||
}
|
|
||||||
throw InternalServerError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (postHogClient) {
|
if (postHogClient) {
|
||||||
postHogClient.capture({
|
postHogClient.capture({
|
||||||
@@ -255,12 +222,7 @@ export const updateSecrets = async (req: Request, res: Response) => {
|
|||||||
const postHogClient = await TelemetryService.getPostHogClient();
|
const postHogClient = await TelemetryService.getPostHogClient();
|
||||||
const { workspaceId, environmentName } = req.params;
|
const { workspaceId, environmentName } = req.params;
|
||||||
const secretsModificationsRequested: ModifySecretRequestBody[] = req.body.secrets;
|
const secretsModificationsRequested: ModifySecretRequestBody[] = req.body.secrets;
|
||||||
const [secretIdsUserCanModifyError, secretIdsUserCanModify] = await to(
|
const secretIdsUserCanModify = await Secret.find({ workspace: workspaceId, environment: environmentName }, { _id: 1 });
|
||||||
Secret.find({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then()
|
|
||||||
);
|
|
||||||
if (secretIdsUserCanModifyError) {
|
|
||||||
throw InternalServerError({ message: "Unable to fetch secrets you own" });
|
|
||||||
}
|
|
||||||
|
|
||||||
const secretsUserCanModifySet: Set<string> = new Set(
|
const secretsUserCanModifySet: Set<string> = new Set(
|
||||||
secretIdsUserCanModify.map((objectId) => objectId._id.toString())
|
secretIdsUserCanModify.map((objectId) => objectId._id.toString())
|
||||||
@@ -298,19 +260,7 @@ export const updateSecrets = async (req: Request, res: Response) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const [bulkModificationInfoError, bulkModificationInfo] = await to(
|
await Secret.bulkWrite(updateOperationsToPerform);
|
||||||
Secret.bulkWrite(updateOperationsToPerform).then()
|
|
||||||
);
|
|
||||||
if (bulkModificationInfoError) {
|
|
||||||
if (bulkModificationInfoError instanceof ValidationError) {
|
|
||||||
throw RouteValidationError({
|
|
||||||
message: "Unable to apply modifications, please try again",
|
|
||||||
stack: bulkModificationInfoError.stack
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
throw InternalServerError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (postHogClient) {
|
if (postHogClient) {
|
||||||
postHogClient.capture({
|
postHogClient.capture({
|
||||||
@@ -340,12 +290,7 @@ export const updateSecret = async (req: Request, res: Response) => {
|
|||||||
const { workspaceId, environmentName } = req.params;
|
const { workspaceId, environmentName } = req.params;
|
||||||
const secretModificationsRequested: ModifySecretRequestBody = req.body.secret;
|
const secretModificationsRequested: ModifySecretRequestBody = req.body.secret;
|
||||||
|
|
||||||
const [secretIdUserCanModifyError, secretIdUserCanModify] = await to(
|
const secretIdUserCanModify = await Secret.findOne({ workspace: workspaceId, environment: environmentName }, { _id: 1 });
|
||||||
Secret.findOne({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then()
|
|
||||||
);
|
|
||||||
if (secretIdUserCanModifyError && !secretIdUserCanModify) {
|
|
||||||
throw BadRequestError();
|
|
||||||
}
|
|
||||||
|
|
||||||
const sanitizedSecret: SanitizedSecretModify = {
|
const sanitizedSecret: SanitizedSecretModify = {
|
||||||
secretKeyCiphertext: secretModificationsRequested.secretKeyCiphertext,
|
secretKeyCiphertext: secretModificationsRequested.secretKeyCiphertext,
|
||||||
@@ -362,18 +307,20 @@ export const updateSecret = async (req: Request, res: Response) => {
|
|||||||
secretCommentHash: secretModificationsRequested.secretCommentHash
|
secretCommentHash: secretModificationsRequested.secretCommentHash
|
||||||
};
|
};
|
||||||
|
|
||||||
const [error, singleModificationUpdate] = await to(
|
const singleModificationUpdate = await Secret.updateOne(
|
||||||
Secret.updateOne(
|
{ _id: secretModificationsRequested._id, workspace: workspaceId },
|
||||||
{ _id: secretModificationsRequested._id, workspace: workspaceId },
|
{ $inc: { version: 1 }, $set: sanitizedSecret }
|
||||||
{ $inc: { version: 1 }, $set: sanitizedSecret }
|
)
|
||||||
).then()
|
.catch((error) => {
|
||||||
);
|
if (error instanceof ValidationError) {
|
||||||
if (error instanceof ValidationError) {
|
throw RouteValidationError({
|
||||||
throw RouteValidationError({
|
message: "Unable to apply modifications, please try again",
|
||||||
message: "Unable to apply modifications, please try again",
|
stack: error.stack
|
||||||
stack: error.stack
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
|
||||||
if (postHogClient) {
|
if (postHogClient) {
|
||||||
postHogClient.capture({
|
postHogClient.capture({
|
||||||
@@ -419,21 +366,18 @@ export const getSecrets = async (req: Request, res: Response) => {
|
|||||||
userEmail = user.email;
|
userEmail = user.email;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [err, secrets] = await to(
|
const secrets = await Secret.find({
|
||||||
Secret.find({
|
workspace: workspaceId,
|
||||||
workspace: workspaceId,
|
environment,
|
||||||
environment,
|
$or: [{ user: userId }, { user: { $exists: false } }],
|
||||||
$or: [{ user: userId }, { user: { $exists: false } }],
|
type: { $in: [SECRET_SHARED, SECRET_PERSONAL] }
|
||||||
type: { $in: [SECRET_SHARED, SECRET_PERSONAL] }
|
})
|
||||||
}).then()
|
.catch((err) => {
|
||||||
);
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
throw RouteValidationError({
|
throw RouteValidationError({
|
||||||
message: "Failed to get secrets, please try again",
|
message: "Failed to get secrets, please try again",
|
||||||
stack: err.stack
|
stack: err.stack
|
||||||
});
|
});
|
||||||
}
|
})
|
||||||
|
|
||||||
if (postHogClient) {
|
if (postHogClient) {
|
||||||
postHogClient.capture({
|
postHogClient.capture({
|
||||||
|
|||||||
@@ -1,32 +1,23 @@
|
|||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
import { Types } from "mongoose";
|
import { Types } from "mongoose";
|
||||||
import { Membership, Secret } from "../../models";
|
import { Membership, Secret } from "../../models";
|
||||||
import Tag, { ITag } from "../../models/tag";
|
import Tag from "../../models/tag";
|
||||||
import { Builder } from "builder-pattern";
|
|
||||||
import to from "await-to-js";
|
|
||||||
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
|
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
|
||||||
import { MongoError } from "mongodb";
|
import { MongoError } from "mongodb";
|
||||||
|
|
||||||
export const createWorkspaceTag = async (req: Request, res: Response) => {
|
export const createWorkspaceTag = async (req: Request, res: Response) => {
|
||||||
const { workspaceId } = req.params;
|
const { workspaceId } = req.params;
|
||||||
const { name, slug } = req.body;
|
const { name, slug } = req.body;
|
||||||
const sanitizedTagToCreate = Builder<ITag>()
|
|
||||||
.name(name)
|
const tagToCreate = {
|
||||||
.workspace(new Types.ObjectId(workspaceId))
|
name,
|
||||||
.slug(slug)
|
workspace: new Types.ObjectId(workspaceId),
|
||||||
.user(new Types.ObjectId(req.user._id))
|
slug,
|
||||||
.build();
|
user: new Types.ObjectId(req.user._id),
|
||||||
|
};
|
||||||
const [err, createdTag] = await to(Tag.create(sanitizedTagToCreate));
|
|
||||||
|
const createdTag = await new Tag(tagToCreate);
|
||||||
if (err) {
|
|
||||||
if ((err as MongoError).code === 11000) {
|
|
||||||
throw BadRequestError({ message: "Tags must be unique in a workspace" });
|
|
||||||
}
|
|
||||||
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(createdTag);
|
res.json(createdTag);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { IMembershipPermission } from "../../../models/membership";
|
|||||||
import { BadRequestError, UnauthorizedRequestError } from "../../../utils/errors";
|
import { BadRequestError, UnauthorizedRequestError } from "../../../utils/errors";
|
||||||
import { ADMIN, MEMBER } from "../../../variables/organization";
|
import { ADMIN, MEMBER } from "../../../variables/organization";
|
||||||
import { PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS } from "../../../variables";
|
import { PERMISSION_READ_SECRETS, PERMISSION_WRITE_SECRETS } from "../../../variables";
|
||||||
import { Builder } from "builder-pattern"
|
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
|
||||||
export const denyMembershipPermissions = async (req: Request, res: Response) => {
|
export const denyMembershipPermissions = async (req: Request, res: Response) => {
|
||||||
@@ -15,10 +14,10 @@ export const denyMembershipPermissions = async (req: Request, res: Response) =>
|
|||||||
throw BadRequestError({ message: "One or more required fields are missing from the request or have incorrect type" })
|
throw BadRequestError({ message: "One or more required fields are missing from the request or have incorrect type" })
|
||||||
}
|
}
|
||||||
|
|
||||||
return Builder<IMembershipPermission>()
|
return {
|
||||||
.environmentSlug(permission.environmentSlug)
|
environmentSlug: permission.environmentSlug,
|
||||||
.ability(permission.ability)
|
ability: permission.ability
|
||||||
.build();
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const sanitizedMembershipPermissionsUnique = _.uniqWith(sanitizedMembershipPermissions, _.isEqual)
|
const sanitizedMembershipPermissionsUnique = _.uniqWith(sanitizedMembershipPermissions, _.isEqual)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
ARG POSTHOG_HOST=https://app.posthog.com
|
ARG POSTHOG_HOST=https://app.posthog.com
|
||||||
ARG POSTHOG_API_KEY=posthog-api-key
|
ARG POSTHOG_API_KEY=posthog-api-key
|
||||||
|
ARG INTERCOM_ID=intercom-id
|
||||||
|
|
||||||
FROM node:16-alpine AS deps
|
FROM node:16-alpine AS deps
|
||||||
# Install dependencies only when needed. Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
# Install dependencies only when needed. Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ export const load = () => {
|
|||||||
|
|
||||||
// Initializes Intercom
|
// Initializes Intercom
|
||||||
export const boot = (options = {}) => {
|
export const boot = (options = {}) => {
|
||||||
|
console.log("boot", { app_id: APP_ID, ...options })
|
||||||
window &&
|
window &&
|
||||||
window.Intercom &&
|
window.Intercom &&
|
||||||
window.Intercom("boot", { app_id: APP_ID, ...options });
|
window.Intercom("boot", { app_id: APP_ID, ...options });
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
|
import { useUser } from "@app/context";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
boot as bootIntercom,
|
boot as bootIntercom,
|
||||||
load as loadIntercom,
|
load as loadIntercom,
|
||||||
@@ -9,11 +11,12 @@ import {
|
|||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
export const IntercomProvider = ({ children }: { children: any }) => {
|
export const IntercomProvider = ({ children }: { children: any }) => {
|
||||||
|
const { user } = useUser();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
loadIntercom();
|
loadIntercom();
|
||||||
bootIntercom();
|
bootIntercom({name: `${user?.firstName || ""} ${user?.lastName || ""}`, email: user?.email || "", created_at: Math.floor(((new Date(user?.createdAt))?.getTime() || 0) / 1000)});
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ export default function Home() {
|
|||||||
icon: faHandPeace,
|
icon: faHandPeace,
|
||||||
time: "3 min",
|
time: "3 min",
|
||||||
userAction: "intro_cta_clicked",
|
userAction: "intro_cta_clicked",
|
||||||
link: "https://www.youtube.com/watch?v=3F7FNYX94zA"
|
link: "https://www.youtube.com/watch?v=PK23097-25I"
|
||||||
})}
|
})}
|
||||||
{learningItem({
|
{learningItem({
|
||||||
text: "Add your secrets",
|
text: "Add your secrets",
|
||||||
|
|||||||
Reference in New Issue
Block a user