fix: toggleEnabled handler (#25325)

* fix toggle enabled handler

* add tests

---------

Co-authored-by: CarinaWolli <[email protected]>
Co-authored-by: Keith Williams <[email protected]>
This commit is contained in:
Carina Wollendorfer
2025-11-21 13:15:04 -03:00
committed by GitHub
co-authored by CarinaWolli Keith Williams
parent c941192979
commit a7aabc8b4f
2 changed files with 161 additions and 0 deletions
@@ -0,0 +1,153 @@
import { describe, it, beforeEach, vi, expect } from "vitest";
import { DelegationCredentialRepository } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository";
import { toggleDelegationCredentialEnabled } from "./toggleEnabled.handler";
// Mock the repository
vi.mock("@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository", () => ({
DelegationCredentialRepository: {
findById: vi.fn(),
updateById: vi.fn(),
findByIdIncludeSensitiveServiceAccountKey: vi.fn(),
},
}));
// Mock other dependencies
vi.mock("@calcom/app-store/delegationCredential", () => ({
checkIfSuccessfullyConfiguredInWorkspace: vi.fn().mockResolvedValue(true),
}));
vi.mock("@calcom/emails/integration-email-service", () => ({
sendDelegationCredentialDisabledEmail: vi.fn(),
}));
vi.mock("./getAffectedMembersForDisable.handler", () => ({
getAffectedMembersForDisable: vi.fn().mockResolvedValue([]),
}));
vi.mock("./utils", () => ({
ensureNoServiceAccountKey: vi.fn((credential) => credential),
}));
describe("toggleDelegationCredentialEnabled - Security Fix", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("should prevent users without organizationId from accessing any credentials", async () => {
const userWithoutOrg = {
id: 1,
email: "[email protected]",
organizationId: null,
};
const input = {
id: "any-credential",
enabled: true,
};
const mockCredential = {
id: "any-credential",
organizationId: 1,
enabled: false,
workspacePlatform: { slug: "google" },
};
vi.mocked(DelegationCredentialRepository.findById).mockResolvedValue(mockCredential);
await expect(
toggleDelegationCredentialEnabled(userWithoutOrg, input)
).rejects.toThrow("You must be part of an organization to toggle a delegation credential");
expect(DelegationCredentialRepository.updateById).not.toHaveBeenCalled();
});
it("should prevent cross-organization access", async () => {
const userFromOrg1 = {
id: 1,
email: "[email protected]",
organizationId: 1,
};
const input = {
id: "org2-credential",
enabled: false,
};
const org2Credential = {
id: "org2-credential",
organizationId: 2, // Different organization
enabled: true,
workspacePlatform: { slug: "google" },
};
vi.mocked(DelegationCredentialRepository.findById).mockResolvedValue(org2Credential);
await expect(
toggleDelegationCredentialEnabled(userFromOrg1, input)
).rejects.toThrow("Delegation credential not found");
expect(DelegationCredentialRepository.updateById).not.toHaveBeenCalled();
});
it("should allow same-organization access", async () => {
const userFromOrg1 = {
id: 1,
email: "[email protected]",
organizationId: 1,
};
const input = {
id: "org1-credential",
enabled: false,
};
const org1Credential = {
id: "org1-credential",
organizationId: 1, // Same organization
enabled: true,
workspacePlatform: { slug: "google" },
};
const updatedCredential = {
...org1Credential,
enabled: false,
lastDisabledAt: new Date(),
};
vi.mocked(DelegationCredentialRepository.findById).mockResolvedValue(org1Credential);
vi.mocked(DelegationCredentialRepository.updateById).mockResolvedValue(updatedCredential);
const result = await toggleDelegationCredentialEnabled(userFromOrg1, input);
expect(result).toEqual(updatedCredential);
expect(DelegationCredentialRepository.updateById).toHaveBeenCalledWith({
id: "org1-credential",
data: {
enabled: false,
lastEnabledAt: undefined,
lastDisabledAt: expect.any(Date),
},
});
});
it("should handle nonexistent credentials", async () => {
const user = {
id: 1,
email: "[email protected]",
organizationId: 1,
};
const input = {
id: "nonexistent-credential",
enabled: true,
};
vi.mocked(DelegationCredentialRepository.findById).mockResolvedValue(null);
await expect(
toggleDelegationCredentialEnabled(user, input)
).rejects.toThrow("Delegation credential not found");
});
});
@@ -53,6 +53,14 @@ export async function toggleDelegationCredentialEnabled(
throw new Error("Delegation credential not found");
}
if (!loggedInUser.organizationId) {
throw new Error("You must be part of an organization to toggle a delegation credential");
}
if (currentDelegationCredential.organizationId !== loggedInUser.organizationId) {
throw new Error("Delegation credential not found");
}
const shouldBeEnabled = input.enabled;
if (shouldBeEnabled === currentDelegationCredential.enabled) {