From 751bbe588fdfb942b5366a800cd49cad450ef6ea Mon Sep 17 00:00:00 2001 From: anudeeps352 Date: Fri, 28 Jun 2024 01:30:30 +0530 Subject: [PATCH 1/5] API: Create endpoint for fetching all revisions of a secret --- .../secret/controller/secret.controller.ts | 14 +++ apps/api/src/secret/secret.e2e.spec.ts | 104 ++++++++++++++++++ apps/api/src/secret/service/secret.service.ts | 29 +++++ 3 files changed, 147 insertions(+) diff --git a/apps/api/src/secret/controller/secret.controller.ts b/apps/api/src/secret/controller/secret.controller.ts index 59f36993..604995fe 100644 --- a/apps/api/src/secret/controller/secret.controller.ts +++ b/apps/api/src/secret/controller/secret.controller.ts @@ -101,4 +101,18 @@ export class SecretController { environmentId ) } + + @Get(':secretId/revisions/:environmentId') + @RequiredApiKeyAuthorities(Authority.READ_SECRET) + async getRevisionsOfSecret( + @CurrentUser() user: User, + @Param('secretId') secretId: string, + @Param('environmentId') environmentId: string + ) { + return await this.secretService.getRevisionsOfSecret( + user, + secretId, + environmentId + ) + } } diff --git a/apps/api/src/secret/secret.e2e.spec.ts b/apps/api/src/secret/secret.e2e.spec.ts index 4efd828b..96a8eff3 100644 --- a/apps/api/src/secret/secret.e2e.spec.ts +++ b/apps/api/src/secret/secret.e2e.spec.ts @@ -920,4 +920,108 @@ describe('Secret Controller Tests', () => { expect(event.workspaceId).toBe(workspace1.id) expect(event.itemId).toBe(secret1.id) }) + + //revisions test + it('should be able to fetch all revisions of secrets', async () => { + // create two more entries,totalling three versions + // checks if its able to fetch multiple revisions + await secretService.updateSecret(user1, secret1.id, { + entries: [ + { + value: 'Updated Secret 1 value', + environmentId: environment1.id + } + ] + }) + + await secretService.updateSecret(user1, secret1.id, { + entries: [ + { + value: 'Updated Secret 1 value 2', + environmentId: environment1.id + } + ] + }) + + const response = await app.inject({ + method: 'GET', + url: `/secret/${secret1.id}/revisions/${environment1.id}`, + headers: { + 'x-e2e-user-email': user1.email + } + }) + + expect(response.statusCode).toBe(200) + expect(response.json().length).toBe(3) + }) + + it('should return [] if the secret has no revision', async () => { + //returns [] if secret has no revision + await prisma.secretVersion.deleteMany({ + where: { + secretId: secret1.id + } + }) + + const response = await app.inject({ + method: 'GET', + url: `/secret/${secret1.id}/revisions/${environment1.id}`, + headers: { + 'x-e2e-user-email': user1.email + } + }) + + expect(response.statusCode).toBe(200) + expect(response.json().length).toBe(0) + }) + + it('should return error if secret doesnt exist', async () => { + //return error if secret doesnt exist + const secretid = 'nonexistentsecret' + const response = await app.inject({ + method: 'GET', + url: `/secret/${secretid}/revisions/${environment1.id}`, + headers: { + 'x-e2e-user-email': user1.email + } + }) + + expect(response.statusCode).toBe(404) + expect(response.json().message).toEqual( + `Secret with id ${secretid} not found` + ) + }) + + it('should return error if environment doesnt exist', async () => { + //return error if environment doesnt exist + const environmentid = 'nonexistentenv' + const response = await app.inject({ + method: 'GET', + url: `/secret/${secret1.id}/revisions/${environmentid}`, + headers: { + 'x-e2e-user-email': user1.email + } + }) + + expect(response.statusCode).toBe(404) + expect(response.json().message).toEqual( + `Environment with id ${environmentid} not found` + ) + }) + + it('returns error if secret isnt accessible', async () => { + //return error if user has no access to secret + const response = await app.inject({ + method: 'GET', + url: `/secret/${secret1.id}/revisions/${environment1.id}`, + headers: { + 'x-e2e-user-email': user2.email + } + }) + + expect(response.statusCode).toBe(401) + expect(response.json().message).toEqual( + `User ${user2.id} does not have the required authorities` + ) + }) }) diff --git a/apps/api/src/secret/service/secret.service.ts b/apps/api/src/secret/service/secret.service.ts index 255d0960..d7f5cfc8 100644 --- a/apps/api/src/secret/service/secret.service.ts +++ b/apps/api/src/secret/service/secret.service.ts @@ -492,6 +492,35 @@ export class SecretService { return response } + async getRevisionsOfSecret( + user: User, + secretId: Secret['id'], + environmentId: Environment['id'] + ) { + //check access to secret + await this.authorityCheckerService.checkAuthorityOverSecret({ + userId: user.id, + entity: { id: secretId }, + authority: Authority.READ_SECRET, + prisma: this.prisma + }) + + await this.authorityCheckerService.checkAuthorityOverEnvironment({ + userId: user.id, + entity: { id: environmentId }, + authority: Authority.READ_ENVIRONMENT, + prisma: this.prisma + }) + + // get the revisions + const revisions = await this.prisma.secretVersion.findMany({ + where: { + secretId: secretId, + environmentId: environmentId + } + }) + return revisions + } async getAllSecretsOfProject( user: User, From 2670240a4e775f7bfb20a8b7043b54b6613e3c0e Mon Sep 17 00:00:00 2001 From: anudeeps352 Date: Fri, 28 Jun 2024 19:52:54 +0530 Subject: [PATCH 2/5] added pagination to getRevisionsOfSecret --- .../api/src/secret/controller/secret.controller.ts | 14 ++++++++++++-- apps/api/src/secret/service/secret.service.ts | 12 +++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/apps/api/src/secret/controller/secret.controller.ts b/apps/api/src/secret/controller/secret.controller.ts index 604995fe..e387fbc4 100644 --- a/apps/api/src/secret/controller/secret.controller.ts +++ b/apps/api/src/secret/controller/secret.controller.ts @@ -107,12 +107,22 @@ export class SecretController { async getRevisionsOfSecret( @CurrentUser() user: User, @Param('secretId') secretId: string, - @Param('environmentId') environmentId: string + @Param('environmentId') environmentId: string, + @Query('page') page: number = 0, + @Query('limit') limit: number = 10, + @Query('sort') sort: string = 'version', + @Query('order') order: string = 'desc', + @Query('search') search: string = '' ) { return await this.secretService.getRevisionsOfSecret( user, secretId, - environmentId + environmentId, + page, + limit, + sort, + order, + search ) } } diff --git a/apps/api/src/secret/service/secret.service.ts b/apps/api/src/secret/service/secret.service.ts index d7f5cfc8..aa7d1be5 100644 --- a/apps/api/src/secret/service/secret.service.ts +++ b/apps/api/src/secret/service/secret.service.ts @@ -495,7 +495,12 @@ export class SecretService { async getRevisionsOfSecret( user: User, secretId: Secret['id'], - environmentId: Environment['id'] + environmentId: Environment['id'], + page: number, + limit: number, + sort: string, + order: string, + search: string ) { //check access to secret await this.authorityCheckerService.checkAuthorityOverSecret({ @@ -517,6 +522,11 @@ export class SecretService { where: { secretId: secretId, environmentId: environmentId + }, + skip: page * limit, + take: limit, + orderBy: { + [sort]: order } }) return revisions From 52b1e75d48116e0245d89e54c4aabe876351e429 Mon Sep 17 00:00:00 2001 From: anudeeps352 Date: Fri, 28 Jun 2024 20:41:10 +0530 Subject: [PATCH 3/5] removed order and search query params --- apps/api/src/secret/controller/secret.controller.ts | 8 ++------ apps/api/src/secret/service/secret.service.ts | 6 ++---- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/apps/api/src/secret/controller/secret.controller.ts b/apps/api/src/secret/controller/secret.controller.ts index e387fbc4..29451583 100644 --- a/apps/api/src/secret/controller/secret.controller.ts +++ b/apps/api/src/secret/controller/secret.controller.ts @@ -110,9 +110,7 @@ export class SecretController { @Param('environmentId') environmentId: string, @Query('page') page: number = 0, @Query('limit') limit: number = 10, - @Query('sort') sort: string = 'version', - @Query('order') order: string = 'desc', - @Query('search') search: string = '' + @Query('sort') sort: string = 'version' ) { return await this.secretService.getRevisionsOfSecret( user, @@ -120,9 +118,7 @@ export class SecretController { environmentId, page, limit, - sort, - order, - search + sort ) } } diff --git a/apps/api/src/secret/service/secret.service.ts b/apps/api/src/secret/service/secret.service.ts index aa7d1be5..e5ee189c 100644 --- a/apps/api/src/secret/service/secret.service.ts +++ b/apps/api/src/secret/service/secret.service.ts @@ -498,9 +498,7 @@ export class SecretService { environmentId: Environment['id'], page: number, limit: number, - sort: string, - order: string, - search: string + sort: string ) { //check access to secret await this.authorityCheckerService.checkAuthorityOverSecret({ @@ -526,7 +524,7 @@ export class SecretService { skip: page * limit, take: limit, orderBy: { - [sort]: order + [sort]: 'desc' } }) return revisions From 8093f0d9efa13732d2ba3071d2f0855c52587804 Mon Sep 17 00:00:00 2001 From: Anudeep <94232161+anudeeps352@users.noreply.github.com> Date: Wed, 24 Jul 2024 21:08:33 +0530 Subject: [PATCH 4/5] Update secret.service.ts Updated sort param --- apps/api/src/secret/service/secret.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/src/secret/service/secret.service.ts b/apps/api/src/secret/service/secret.service.ts index e5ee189c..7e07a360 100644 --- a/apps/api/src/secret/service/secret.service.ts +++ b/apps/api/src/secret/service/secret.service.ts @@ -524,7 +524,7 @@ export class SecretService { skip: page * limit, take: limit, orderBy: { - [sort]: 'desc' + [sort]: sort } }) return revisions From 85668fea2e927afa75af884785fbf61701b93e8d Mon Sep 17 00:00:00 2001 From: anudeeps352 Date: Sun, 28 Jul 2024 01:28:24 +0530 Subject: [PATCH 5/5] added order param and removed sort param --- apps/api/src/secret/controller/secret.controller.ts | 4 ++-- apps/api/src/secret/service/secret.service.ts | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/api/src/secret/controller/secret.controller.ts b/apps/api/src/secret/controller/secret.controller.ts index 29451583..16274f11 100644 --- a/apps/api/src/secret/controller/secret.controller.ts +++ b/apps/api/src/secret/controller/secret.controller.ts @@ -110,7 +110,7 @@ export class SecretController { @Param('environmentId') environmentId: string, @Query('page') page: number = 0, @Query('limit') limit: number = 10, - @Query('sort') sort: string = 'version' + @Query('order') order: string = 'desc' ) { return await this.secretService.getRevisionsOfSecret( user, @@ -118,7 +118,7 @@ export class SecretController { environmentId, page, limit, - sort + order ) } } diff --git a/apps/api/src/secret/service/secret.service.ts b/apps/api/src/secret/service/secret.service.ts index 7e07a360..156c5238 100644 --- a/apps/api/src/secret/service/secret.service.ts +++ b/apps/api/src/secret/service/secret.service.ts @@ -498,8 +498,10 @@ export class SecretService { environmentId: Environment['id'], page: number, limit: number, - sort: string + order: string ) { + // assign order to variable dynamically + const sortOrder = order === 'asc' ? 'asc' : 'desc' //check access to secret await this.authorityCheckerService.checkAuthorityOverSecret({ userId: user.id, @@ -524,7 +526,7 @@ export class SecretService { skip: page * limit, take: limit, orderBy: { - [sort]: sort + version: sortOrder } }) return revisions