fix: improve environment validation in published docs (#5962)

This commit is contained in:
sahilkhan09k 2026-04-22 21:25:10 +05:30 committed by GitHub
parent eb801889ba
commit bc3dbdea42
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 68 additions and 41 deletions

View file

@ -462,6 +462,12 @@ export const USER_ENVIRONMENT_IS_NOT_GLOBAL =
export const USER_ENVIRONMENT_UPDATE_FAILED =
'user_environment/user_env_update_failed' as const;
/**
* User environment not found for the user
* (UserEnvironmentsService)
*/
export const USER_ENVIRONMENT_NOT_FOUND = 'user_environment/not_found' as const;
/**
* User environment invalid environment name
* (UserEnvironmentsService)
@ -977,8 +983,8 @@ export const PUBLISHED_DOCS_DELETION_FAILED = 'published_docs/deletion_failed';
* Published Docs invalid environment
* (PublishedDocsService)
*/
export const PUBLISHED_DOCS_INVALID_ENVIRONMENT =
'published_docs/invalid_environment';
export const PUBLISHED_DOCS_FORBIDDEN_ENVIRONMENT_ACCESS =
'published_docs/forbidden_environment_access';
/**
* Published Docs not found

View file

@ -4,10 +4,12 @@ import {
PUBLISHED_DOCS_CREATION_FAILED,
PUBLISHED_DOCS_DELETION_FAILED,
PUBLISHED_DOCS_INVALID_COLLECTION,
PUBLISHED_DOCS_INVALID_ENVIRONMENT,
PUBLISHED_DOCS_FORBIDDEN_ENVIRONMENT_ACCESS,
PUBLISHED_DOCS_NOT_FOUND,
PUBLISHED_DOCS_UPDATE_FAILED,
TEAM_ENVIRONMENT_NOT_FOUND,
TEAM_INVALID_ID,
USER_ENVIRONMENT_NOT_FOUND,
} from 'src/errors';
import * as E from 'fp-ts/Either';
import { PrismaService } from 'src/prisma/prisma.service';
@ -1491,7 +1493,7 @@ describe('createPublishedDoc - environment support', () => {
userUid: user.uid,
} as any);
mockPrisma.publishedDocs.findFirst.mockResolvedValueOnce(null);
mockPrisma.userEnvironment.findFirst.mockResolvedValueOnce(envData as any);
mockPrisma.userEnvironment.findUnique.mockResolvedValueOnce(envData as any);
mockPrisma.publishedDocs.create.mockResolvedValueOnce({
...userPublishedDoc,
environmentID: 'env_1',
@ -1537,7 +1539,7 @@ describe('createPublishedDoc - environment support', () => {
teamID: 'team_1',
} as any);
mockPrisma.publishedDocs.findFirst.mockResolvedValueOnce(null);
mockPrisma.teamEnvironment.findFirst.mockResolvedValueOnce(envData as any);
mockPrisma.teamEnvironment.findUnique.mockResolvedValueOnce(envData as any);
mockPrisma.publishedDocs.create.mockResolvedValueOnce({
...teamPublishedDoc,
environmentID: 'team_env_1',
@ -1568,14 +1570,14 @@ describe('createPublishedDoc - environment support', () => {
userUid: user.uid,
} as any);
mockPrisma.publishedDocs.findFirst.mockResolvedValueOnce(null);
mockPrisma.userEnvironment.findFirst.mockResolvedValueOnce(null);
mockPrisma.userEnvironment.findUnique.mockResolvedValueOnce(null);
const result = await publishedDocsService.createPublishedDoc(
{ ...createArgs, environmentID: 'invalid_env' },
user,
);
expect(result).toEqualLeft(PUBLISHED_DOCS_INVALID_ENVIRONMENT);
expect(result).toEqualLeft(USER_ENVIRONMENT_NOT_FOUND);
});
test('should return error when team environment ID is invalid', async () => {
@ -1593,14 +1595,14 @@ describe('createPublishedDoc - environment support', () => {
teamID: 'team_1',
} as any);
mockPrisma.publishedDocs.findFirst.mockResolvedValueOnce(null);
mockPrisma.teamEnvironment.findFirst.mockResolvedValueOnce(null);
mockPrisma.teamEnvironment.findUnique.mockResolvedValueOnce(null);
const result = await publishedDocsService.createPublishedDoc(
teamArgs,
user,
);
expect(result).toEqualLeft(PUBLISHED_DOCS_INVALID_ENVIRONMENT);
expect(result).toEqualLeft(TEAM_ENVIRONMENT_NOT_FOUND);
});
test('should create published doc without environment when environmentID is not provided', async () => {
@ -1640,7 +1642,7 @@ describe('updatePublishedDoc - environment support', () => {
};
mockPrisma.publishedDocs.findUnique.mockResolvedValueOnce(userPublishedDoc);
mockPrisma.userEnvironment.findFirst.mockResolvedValueOnce(envData as any);
mockPrisma.userEnvironment.findUnique.mockResolvedValueOnce(envData as any);
mockPrisma.publishedDocs.update.mockResolvedValueOnce({
...userPublishedDoc,
environmentID: 'env_2',
@ -1701,7 +1703,7 @@ describe('updatePublishedDoc - environment support', () => {
test('should return error when updating with invalid environment ID', async () => {
mockPrisma.publishedDocs.findUnique.mockResolvedValueOnce(userPublishedDoc);
mockPrisma.userEnvironment.findFirst.mockResolvedValueOnce(null);
mockPrisma.userEnvironment.findUnique.mockResolvedValueOnce(null);
const result = await publishedDocsService.updatePublishedDoc(
userPublishedDoc.id,
@ -1709,7 +1711,7 @@ describe('updatePublishedDoc - environment support', () => {
user,
);
expect(result).toEqualLeft(PUBLISHED_DOCS_INVALID_ENVIRONMENT);
expect(result).toEqualLeft(USER_ENVIRONMENT_NOT_FOUND);
});
test('should not change environment when environmentID is not provided in update args', async () => {
@ -1743,7 +1745,7 @@ describe('updatePublishedDoc - environment support', () => {
mockPrisma.publishedDocs.findUnique.mockResolvedValueOnce(teamPublishedDoc);
mockPrisma.team.findFirst.mockResolvedValueOnce({ id: 'team_1' } as any);
mockPrisma.teamEnvironment.findFirst.mockResolvedValueOnce(envData as any);
mockPrisma.teamEnvironment.findUnique.mockResolvedValueOnce(envData as any);
mockPrisma.publishedDocs.update.mockResolvedValueOnce({
...teamPublishedDoc,
environmentID: 'team_env_1',
@ -1796,7 +1798,7 @@ describe('getPublishedDocBySlugPublic - environment support', () => {
mockUserCollectionService.exportUserCollectionToJSONObject.mockResolvedValueOnce(
E.right(collectionData as any),
);
mockPrisma.userEnvironment.findFirst.mockResolvedValueOnce(envData as any);
mockPrisma.userEnvironment.findUnique.mockResolvedValueOnce(envData as any);
const result = await publishedDocsService.getPublishedDocBySlugPublic(
'slug-collection-1',
@ -1894,14 +1896,14 @@ describe('getPublishedDocBySlugPublic - environment support', () => {
E.right(collectionData as any),
);
// Environment not found — fetchEnvironment returns Left
mockPrisma.userEnvironment.findFirst.mockResolvedValueOnce(null);
mockPrisma.userEnvironment.findUnique.mockResolvedValueOnce(null);
const result = await publishedDocsService.getPublishedDocBySlugPublic(
'slug-collection-1',
'1.0.0',
);
expect(result).toEqualLeft(PUBLISHED_DOCS_INVALID_ENVIRONMENT);
expect(result).toEqualLeft(USER_ENVIRONMENT_NOT_FOUND);
});
test('should return null environment fields when no environment is associated', async () => {

View file

@ -13,12 +13,14 @@ import {
PUBLISHED_DOCS_CREATION_FAILED,
PUBLISHED_DOCS_DELETION_FAILED,
PUBLISHED_DOCS_INVALID_COLLECTION,
PUBLISHED_DOCS_INVALID_ENVIRONMENT,
PUBLISHED_DOCS_FORBIDDEN_ENVIRONMENT_ACCESS,
PUBLISHED_DOCS_NOT_FOUND,
PUBLISHED_DOCS_UPDATE_FAILED,
TEAM_ENVIRONMENT_NOT_FOUND,
TEAM_INVALID_COLL_ID,
TEAM_INVALID_ID,
USER_COLL_NOT_FOUND,
USER_ENVIRONMENT_NOT_FOUND,
} from 'src/errors';
import * as E from 'fp-ts/Either';
import { PublishedDocs, PublishedDocsVersion } from './published-docs.model';
@ -100,22 +102,43 @@ export class PublishedDocsService {
environmentID: string,
workspaceType: WorkspaceType,
workspaceID: string,
): Promise<E.Either<string, { name: string; variables: JsonValue } | null>> {
): Promise<E.Either<string, { name: string; variables: JsonValue }>> {
// TEAM workspace environment
if (workspaceType === WorkspaceType.TEAM) {
const env = await this.prisma.teamEnvironment.findFirst({
where: { id: environmentID, teamID: workspaceID },
const env = await this.prisma.teamEnvironment.findUnique({
where: { id: environmentID },
});
if (!env) return E.left(PUBLISHED_DOCS_INVALID_ENVIRONMENT);
return E.right({ name: env.name, variables: env.variables });
} else if (workspaceType === WorkspaceType.USER) {
const env = await this.prisma.userEnvironment.findFirst({
where: { id: environmentID, userUid: workspaceID },
if (!env) return E.left(TEAM_ENVIRONMENT_NOT_FOUND);
// Validate environment exists and belongs to the correct team
if (env.teamID !== workspaceID)
return E.left(PUBLISHED_DOCS_FORBIDDEN_ENVIRONMENT_ACCESS);
return E.right({
name: env.name,
variables: env.variables,
});
if (!env) return E.left(PUBLISHED_DOCS_INVALID_ENVIRONMENT);
return E.right({ name: env.name ?? '', variables: env.variables });
}
return E.left(PUBLISHED_DOCS_INVALID_ENVIRONMENT);
// USER workspace environment
if (workspaceType === WorkspaceType.USER) {
const env = await this.prisma.userEnvironment.findUnique({
where: { id: environmentID },
});
if (!env) return E.left(USER_ENVIRONMENT_NOT_FOUND);
// Validate environment exists and belongs to the correct user
if (env.userUid !== workspaceID) {
return E.left(PUBLISHED_DOCS_FORBIDDEN_ENVIRONMENT_ACCESS);
}
return E.right({
name: env.name ?? '',
variables: env.variables,
});
}
return E.left(PUBLISHED_DOCS_FORBIDDEN_ENVIRONMENT_ACCESS);
}
/**
@ -368,11 +391,9 @@ export class PublishedDocsService {
);
if (E.isLeft(envResult)) return E.left(envResult.left);
if (E.isRight(envResult) && envResult.right) {
environmentName = envResult.right.name;
environmentVariables = envResult.right.variables;
}
}
docToReturn = {
...publishedDocs,
@ -577,11 +598,10 @@ export class PublishedDocsService {
workspaceID,
);
if (E.isLeft(envResult)) return E.left(envResult.left);
if (envResult.right) {
environmentName = envResult.right.name;
environmentVariables = envResult.right.variables;
}
}
// Attempt to create the published document
const newPublishedDoc = await this.prisma.publishedDocs.create({
@ -697,13 +717,12 @@ export class PublishedDocsService {
publishedDocs.workspaceID,
);
if (E.isLeft(envResult)) return E.left(envResult.left);
if (envResult.right) {
environmentID = args.environmentID;
environmentName = envResult.right.name;
environmentVariables = envResult.right.variables;
}
}
}
// Update published document
const updatedPublishedDoc = await this.prisma.publishedDocs.update({