Patch delete user, org, project session impl and account for orgId in localStorage

This commit is contained in:
Tuan Dang
2023-10-13 11:22:40 +01:00
parent a56a135396
commit 0a53b72cce
9 changed files with 235 additions and 30 deletions
+98 -5
View File
@@ -1,4 +1,4 @@
import mongoose, { Types } from "mongoose"; import mongoose, { Types, mongo } from "mongoose";
import { import {
Bot, Bot,
BotKey, BotKey,
@@ -111,48 +111,78 @@ export const createOrganization = async ({
* @returns * @returns
*/ */
export const deleteOrganization = async ({ export const deleteOrganization = async ({
organizationId organizationId,
existingSession
}: { }: {
organizationId: Types.ObjectId; organizationId: Types.ObjectId;
existingSession?: mongo.ClientSession;
}) => { }) => {
const session = await mongoose.startSession();
let session;
if (existingSession) {
session = existingSession;
} else {
session = await mongoose.startSession();
session.startTransaction(); session.startTransaction();
}
try { try {
const organization = await Organization.findByIdAndDelete(organizationId); const organization = await Organization.findByIdAndDelete(
organizationId,
{
session
}
);
if (!organization) throw ResourceNotFoundError(); if (!organization) throw ResourceNotFoundError();
await MembershipOrg.deleteMany({ await MembershipOrg.deleteMany({
organization: organization._id organization: organization._id
}, {
session
}); });
await BotOrg.deleteMany({ await BotOrg.deleteMany({
organization: organization._id organization: organization._id
}, {
session
}); });
await SSOConfig.deleteMany({ await SSOConfig.deleteMany({
organization: organization._id organization: organization._id
}, {
session
}); });
await Role.deleteMany({ await Role.deleteMany({
organization: organization._id organization: organization._id
}, {
session
}); });
await IncidentContactOrg.deleteMany({ await IncidentContactOrg.deleteMany({
organization: organization._id organization: organization._id
}, {
session
}); });
await GitRisks.deleteMany({ await GitRisks.deleteMany({
organization: organization._id organization: organization._id
}, {
session
}); });
await GitAppInstallationSession.deleteMany({ await GitAppInstallationSession.deleteMany({
organization: organization._id organization: organization._id
}, {
session
}); });
await GitAppOrganizationInstallation.deleteMany({ await GitAppOrganizationInstallation.deleteMany({
organization: organization._id organization: organization._id
}, {
session
}); });
const workspaceIds = await Workspace.distinct("_id", { const workspaceIds = await Workspace.distinct("_id", {
@@ -161,168 +191,231 @@ export const deleteOrganization = async ({
await Workspace.deleteMany({ await Workspace.deleteMany({
organization: organization._id organization: organization._id
}, {
session
}); });
await Membership.deleteMany({ await Membership.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await Key.deleteMany({ await Key.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await Bot.deleteMany({ await Bot.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await BotKey.deleteMany({ await BotKey.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await SecretBlindIndexData.deleteMany({ await SecretBlindIndexData.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await Secret.deleteMany({ await Secret.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await SecretVersion.deleteMany({ await SecretVersion.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await SecretSnapshot.deleteMany({ await SecretSnapshot.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await SecretImport.deleteMany({ await SecretImport.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await Folder.deleteMany({ await Folder.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await FolderVersion.deleteMany({ await FolderVersion.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await Webhook.deleteMany({ await Webhook.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await TrustedIP.deleteMany({ await TrustedIP.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await Tag.deleteMany({ await Tag.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await IntegrationAuth.deleteMany({ await IntegrationAuth.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await Integration.deleteMany({ await Integration.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await ServiceToken.deleteMany({ await ServiceToken.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await ServiceTokenData.deleteMany({ await ServiceTokenData.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await ServiceTokenDataV3.deleteMany({ await ServiceTokenDataV3.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await ServiceTokenDataV3Key.deleteMany({ await ServiceTokenDataV3Key.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await AuditLog.deleteMany({ await AuditLog.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await Log.deleteMany({ await Log.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await Action.deleteMany({ await Action.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await SecretApprovalPolicy.deleteMany({ await SecretApprovalPolicy.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
await SecretApprovalRequest.deleteMany({ await SecretApprovalRequest.deleteMany({
workspace: { workspace: {
$in: workspaceIds $in: workspaceIds
} }
}, {
session
}); });
if (organization.customerId) {
// delete from stripe here
await licenseServerKeyRequest.delete(
`${await getLicenseServerUrl()}/api/license-server/v1/customers/${organization.customerId}`
);
}
return organization; return organization;
} catch (err) { } catch (err) {
if (!existingSession) {
await session.abortTransaction(); await session.abortTransaction();
}
throw InternalServerError({ throw InternalServerError({
message: "Failed to delete organization" message: "Failed to delete organization"
}); });
} finally { } finally {
if (!existingSession) {
await session.commitTransaction();
session.endSession(); session.endSession();
} }
}
} }
/** /**
+45 -7
View File
@@ -1,4 +1,4 @@
import mongoose, { Types } from "mongoose"; import mongoose, { Types, mongo } from "mongoose";
import { import {
APIKeyData, APIKeyData,
BackupPrivateKey, BackupPrivateKey,
@@ -222,15 +222,26 @@ const checkDeleteUserConditions = async ({
* @returns {User} user - deleted user * @returns {User} user - deleted user
*/ */
export const deleteUser = async ({ export const deleteUser = async ({
userId userId,
existingSession
}: { }: {
userId: Types.ObjectId userId: Types.ObjectId;
existingSession?: mongo.ClientSession;
}) => { }) => {
const session = await mongoose.startSession();
let session;
if (existingSession) {
session = existingSession;
} else {
session = await mongoose.startSession();
session.startTransaction(); session.startTransaction();
}
try { try {
const user = await User.findByIdAndDelete(userId); const user = await User.findByIdAndDelete(userId, {
session
});
if (!user) throw ResourceNotFoundError(); if (!user) throw ResourceNotFoundError();
@@ -240,22 +251,32 @@ export const deleteUser = async ({
await UserAction.deleteMany({ await UserAction.deleteMany({
user: user._id user: user._id
}, {
session
}); });
await BackupPrivateKey.deleteMany({ await BackupPrivateKey.deleteMany({
user: user._id user: user._id
}, {
session
}); });
await APIKeyData.deleteMany({ await APIKeyData.deleteMany({
user: user._id user: user._id
}, {
session
}); });
await Action.deleteMany({ await Action.deleteMany({
user: user._id user: user._id
}, {
session
}); });
await Log.deleteMany({ await Log.deleteMany({
user: user._id user: user._id
}, {
session
}); });
await TokenVersion.deleteMany({ await TokenVersion.deleteMany({
@@ -264,10 +285,14 @@ export const deleteUser = async ({
await Key.deleteMany({ await Key.deleteMany({
receiver: user._id receiver: user._id
}, {
session
}); });
const membershipOrgs = await MembershipOrg.find({ const membershipOrgs = await MembershipOrg.find({
user: userId user: userId
}, null, {
session
}); });
// delete organizations where user is only member // delete organizations where user is only member
@@ -280,13 +305,16 @@ export const deleteUser = async ({
// organization only has 1 member (the current user) // organization only has 1 member (the current user)
await deleteOrganization({ await deleteOrganization({
organizationId: membershipOrg.organization organizationId: membershipOrg.organization,
existingSession: session
}); });
} }
} }
const memberships = await Membership.find({ const memberships = await Membership.find({
user: userId user: userId
}, null, {
session
}); });
// delete workspaces where user is only member // delete workspaces where user is only member
@@ -299,26 +327,36 @@ export const deleteUser = async ({
// workspace only has 1 member (the current user) -> delete workspace // workspace only has 1 member (the current user) -> delete workspace
await deleteWorkspace({ await deleteWorkspace({
workspaceId: membership.workspace workspaceId: membership.workspace,
existingSession: session
}); });
} }
} }
await MembershipOrg.deleteMany({ await MembershipOrg.deleteMany({
user: userId user: userId
}, {
session
}); });
await Membership.deleteMany({ await Membership.deleteMany({
user: userId user: userId
}, {
session
}); });
return user; return user;
} catch (err) { } catch (err) {
if (!existingSession) {
await session.abortTransaction(); await session.abortTransaction();
}
throw InternalServerError({ throw InternalServerError({
message: "Failed to delete account" message: "Failed to delete account"
}) })
} finally { } finally {
if (!existingSession) {
await session.commitTransaction();
session.endSession(); session.endSession();
} }
}
} }
+68 -4
View File
@@ -1,4 +1,4 @@
import mongoose, { Types } from "mongoose"; import mongoose, { Types, mongo } from "mongoose";
import { import {
Bot, Bot,
BotKey, BotKey,
@@ -102,125 +102,189 @@ export const createWorkspace = async ({
* @param {String} obj.id - id of workspace to delete * @param {String} obj.id - id of workspace to delete
*/ */
export const deleteWorkspace = async ({ export const deleteWorkspace = async ({
workspaceId workspaceId,
existingSession
}: { }: {
workspaceId: Types.ObjectId; workspaceId: Types.ObjectId;
existingSession?: mongo.ClientSession;
}) => { }) => {
const session = await mongoose.startSession();
let session;
if (existingSession) {
session = existingSession;
} else {
session = await mongoose.startSession();
session.startTransaction(); session.startTransaction();
}
try { try {
const workspace = await Workspace.findByIdAndDelete(workspaceId); const workspace = await Workspace.findByIdAndDelete(workspaceId, { session });
if (!workspace) throw ResourceNotFoundError(); if (!workspace) throw ResourceNotFoundError();
await Membership.deleteMany({ await Membership.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await Key.deleteMany({ await Key.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await Bot.deleteMany({ await Bot.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await BotKey.deleteMany({ await BotKey.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await SecretBlindIndexData.deleteMany({ await SecretBlindIndexData.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await Secret.deleteMany({ await Secret.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await SecretVersion.deleteMany({ await SecretVersion.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await SecretSnapshot.deleteMany({ await SecretSnapshot.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await SecretImport.deleteMany({ await SecretImport.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await Folder.deleteMany({ await Folder.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await FolderVersion.deleteMany({ await FolderVersion.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await Webhook.deleteMany({ await Webhook.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await TrustedIP.deleteMany({ await TrustedIP.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await Tag.deleteMany({ await Tag.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await IntegrationAuth.deleteMany({ await IntegrationAuth.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await Integration.deleteMany({ await Integration.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await ServiceToken.deleteMany({ await ServiceToken.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await ServiceTokenData.deleteMany({ await ServiceTokenData.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await ServiceTokenDataV3.deleteMany({ await ServiceTokenDataV3.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await ServiceTokenDataV3Key.deleteMany({ await ServiceTokenDataV3Key.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await AuditLog.deleteMany({ await AuditLog.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await Log.deleteMany({ await Log.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await Action.deleteMany({ await Action.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await SecretApprovalPolicy.deleteMany({ await SecretApprovalPolicy.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
await SecretApprovalRequest.deleteMany({ await SecretApprovalRequest.deleteMany({
workspace: workspace._id workspace: workspace._id
}, {
session
}); });
return workspace; return workspace;
} catch (err) { } catch (err) {
if (!existingSession) {
await session.abortTransaction(); await session.abortTransaction();
}
throw InternalServerError({ throw InternalServerError({
message: "Failed to delete organization" message: "Failed to delete organization"
}); });
} finally { } finally {
if (!existingSession) {
await session.commitTransaction();
session.endSession(); session.endSession();
} }
}
}; };
+11
View File
@@ -51,6 +51,17 @@ export const useDeleteUser = () => {
return user; return user;
}, },
onSuccess: () => { onSuccess: () => {
localStorage.removeItem("protectedKey");
localStorage.removeItem("protectedKeyIV");
localStorage.removeItem("protectedKeyTag");
localStorage.removeItem("publicKey");
localStorage.removeItem("encryptedPrivateKey");
localStorage.removeItem("iv");
localStorage.removeItem("tag");
localStorage.removeItem("PRIVATE_KEY");
localStorage.removeItem("orgData.id");
localStorage.removeItem("projectData.id");
queryClient.clear(); queryClient.clear();
} }
}); });
@@ -34,7 +34,6 @@ import * as yup from "yup";
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
import { OrgPermissionCan } from "@app/components/permissions"; import { OrgPermissionCan } from "@app/components/permissions";
import onboardingCheck from "@app/components/utilities/checks/OnboardingCheck";
import { tempLocalStorage } from "@app/components/utilities/checks/tempLocalStorage"; import { tempLocalStorage } from "@app/components/utilities/checks/tempLocalStorage";
import { encryptAssymmetric } from "@app/components/utilities/cryptography/crypto"; import { encryptAssymmetric } from "@app/components/utilities/cryptography/crypto";
import { import {
@@ -214,7 +213,6 @@ export const AppLayout = ({ children }: LayoutProps) => {
// } // }
}; };
putUserInOrg(); putUserInOrg();
onboardingCheck({});
}, [router.query.id]); }, [router.query.id]);
const onCreateProject = async ({ name, addMembers }: TAddProjectFormData) => { const onCreateProject = async ({ name, addMembers }: TAddProjectFormData) => {
+1
View File
@@ -12,6 +12,7 @@ export const navigateUserToOrg = async (router: NextRouter) => {
router.push(`/org/${userOrg}/overview`); router.push(`/org/${userOrg}/overview`);
} else { } else {
// user is not part of any org // user is not part of any org
localStorage.removeItem("orgData.id");
router.push("/org/none"); router.push("/org/none");
} }
} }
@@ -50,6 +50,8 @@ export const NonePage = () => {
name name
}); });
localStorage.setItem("orgData.id", organization._id);
createNotification({ createNotification({
text: "Successfully created organization", text: "Successfully created organization",
type: "success" type: "success"
@@ -54,9 +54,7 @@ export const SecretTagsSection = (): JSX.Element => {
colorSchema="secondary" colorSchema="secondary"
leftIcon={<FontAwesomeIcon icon={faPlus} />} leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => { onClick={() => {
console.log("x");
handlePopUpOpen("CreateSecretTag"); handlePopUpOpen("CreateSecretTag");
console.log("x2");
}} }}
isDisabled={!isAllowed} isDisabled={!isAllowed}
> >