Skip to content

Commit

Permalink
added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rajdip-b committed Jun 27, 2024
1 parent 64747bc commit 4396498
Show file tree
Hide file tree
Showing 6 changed files with 253 additions and 5 deletions.
38 changes: 37 additions & 1 deletion apps/api/src/api-key/api-key.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { MAIL_SERVICE } from '../mail/services/interface.service'
import { MockMailService } from '../mail/services/mock.service'
import { AppModule } from '../app/app.module'
import { Test } from '@nestjs/testing'
import { ApiKey, User } from '@prisma/client'
import { ApiKey, Authority, User } from '@prisma/client'
import { ApiKeyService } from './service/api-key.service'

describe('Api Key Role Controller Tests', () => {
Expand Down Expand Up @@ -252,6 +252,42 @@ describe('Api Key Role Controller Tests', () => {
expect(response.statusCode).toBe(401)
})

it('should be able to access live updates if API key has the required authorities', async () => {
// Create a new API key with the required authorities
const newApiKey = await apiKeyService.createApiKey(user, {
name: 'Test Key 2',
authorities: [
Authority.READ_SECRET,
Authority.READ_VARIABLE,
Authority.READ_ENVIRONMENT,
Authority.READ_PROJECT,
Authority.READ_WORKSPACE
]
})

const response = await app.inject({
method: 'GET',
url: '/api-key/access/live-updates',
headers: {
'x-keyshade-token': newApiKey.value
}
})

expect(response.statusCode).toBe(200)
})

it('should not be able to access live updates if API key does not have the required authorities', async () => {
const response = await app.inject({
method: 'GET',
url: '/api-key/access/live-updates',
headers: {
'x-keyshade-token': apiKey.value
}
})

expect(response.statusCode).toBe(401)
})

it('should be able to delete the api key', async () => {
const response = await app.inject({
method: 'DELETE',
Expand Down
125 changes: 125 additions & 0 deletions apps/api/src/secret/secret.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,26 @@ describe('Secret Controller Tests', () => {
expect(secretVersion.length).toBe(2)
})

it('should fail to create a new version if the environment does not exist', async () => {
const response = await app.inject({
method: 'PUT',
url: `/secret/${secret1.id}`,
payload: {
entries: [
{
value: 'Updated Secret 1 value',
environmentId: 'non-existing-environment-id'
}
]
},
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(404)
})

it('should have created a SECRET_UPDATED event', async () => {
// Update a secret
await secretService.updateSecret(user1, secret1.id, {
Expand Down Expand Up @@ -696,6 +716,111 @@ describe('Secret Controller Tests', () => {
)
})

it('should be able to fetch all secrets by project and environment', async () => {
const response = await app.inject({
method: 'GET',
url: `/secret/all/${project1.id}/${environment1.id}`,
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(200)
expect(response.json().length).toBe(1)

const secret = response.json()[0]
expect(secret.name).toBe('Secret 1')
expect(secret.value).toBe('Secret 1 value')
expect(secret.isPlaintext).toBe(true)
})

it('should not be able to fetch all secrets by project and environment if project does not exists', async () => {
const response = await app.inject({
method: 'GET',
url: `/secret/all/non-existing-project-id/${environment1.id}`,
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(404)
expect(response.json().message).toEqual(
'Project with id non-existing-project-id not found'
)
})

it('should not be able to fetch all secrets by project and environment if environment does not exists', async () => {
const response = await app.inject({
method: 'GET',
url: `/secret/all/${project1.id}/non-existing-environment-id`,
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(404)
expect(response.json().message).toEqual(
'Environment with id non-existing-environment-id not found'
)
})

it('should not be able to fetch all secrets by project and environment if the user has no access to the project', async () => {
const response = await app.inject({
method: 'GET',
url: `/secret/all/${project1.id}/${environment1.id}`,
headers: {
'x-e2e-user-email': user2.email
}
})

expect(response.statusCode).toBe(401)
expect(response.json().message).toEqual(
`User with id ${user2.id} does not have the authority in the project with id ${project1.id}`
)
})

it('should not be sending the plaintext secret if project does not store the private key', async () => {
// Get the first environment of project 2
const environment = await prisma.environment.findFirst({
where: {
projectId: project2.id
}
})

// Create a secret in project 2
await secretService.createSecret(
user1,
{
name: 'Secret 20',
entries: [
{
environmentId: environment.id,
value: 'Secret 20 value'
}
],
rotateAfter: '24',
note: 'Secret 20 note'
},
project2.id
)

const response = await app.inject({
method: 'GET',
url: `/secret/all/${project2.id}/${environment.id}`,
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(200)
expect(response.json().length).toBe(1)

const secret = response.json()[0]
expect(secret.name).toBe('Secret 20')
expect(secret.value).not.toBe('Secret 20 value')
expect(secret.isPlaintext).toBe(false)
})

it('should not be able to delete a non-existing secret', async () => {
const response = await app.inject({
method: 'DELETE',
Expand Down
12 changes: 10 additions & 2 deletions apps/api/src/secret/service/secret.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ export class SecretService {
value: project.storePrivateKey
? await decrypt(project.privateKey, secret.versions[0].value)
: secret.versions[0].value,
isPlaintext: !project.storePrivateKey
isPlaintext: project.storePrivateKey
} as ChangeNotificationEvent)
)
} catch (error) {
Expand Down Expand Up @@ -440,6 +440,14 @@ export class SecretService {
prisma: this.prisma
})

// Check access to the environment
await this.authorityCheckerService.checkAuthorityOverEnvironment({
userId: user.id,
entity: { id: environmentId },
authority: Authority.READ_ENVIRONMENT,
prisma: this.prisma
})

const secrets = await this.prisma.secret.findMany({
where: {
projectId,
Expand Down Expand Up @@ -476,7 +484,7 @@ export class SecretService {
value: project.storePrivateKey
? await decrypt(project.privateKey, secret.versions[0].value)
: secret.versions[0].value,
isPlaintext: !project.storePrivateKey
isPlaintext: project.storePrivateKey
})
}

Expand Down
1 change: 0 additions & 1 deletion apps/api/src/variable/service/variable.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ export class VariableService {
variableId: Variable['id'],
dto: UpdateVariable
) {
console.log(dto)
const variable =
await this.authorityCheckerService.checkAuthorityOverVariable({
userId: user.id,
Expand Down
80 changes: 80 additions & 0 deletions apps/api/src/variable/variable.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,26 @@ describe('Variable Controller Tests', () => {
expect(variableVersion.length).toBe(2)
})

it('should fail to create a new version if the environment does not exist', async () => {
const response = await app.inject({
method: 'PUT',
url: `/variable/${variable1.id}`,
payload: {
entries: [
{
value: 'Updated Variable 1 value',
environmentId: 'non-existing-environment-id'
}
]
},
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(404)
})

it('should have created a VARIABLE_UPDATED event', async () => {
// Update a variable
await variableService.updateVariable(user1, variable1.id, {
Expand Down Expand Up @@ -602,6 +622,66 @@ describe('Variable Controller Tests', () => {
)
})

it('should be able to fetch all variables by project and environment', async () => {
const response = await app.inject({
method: 'GET',
url: `/variable/all/${project1.id}/${environment1.id}`,
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(200)
expect(response.json().length).toBe(1)

const variable = response.json()[0]
expect(variable.name).toBe('Variable 1')
expect(variable.value).toBe('Variable 1 value')
expect(variable.isPlaintext).toBe(true)
})

it('should not be able to fetch all variables by project and environment if the user has no access to the project', async () => {
const response = await app.inject({
method: 'GET',
url: `/variable/all/${project1.id}/${environment1.id}`,
headers: {
'x-e2e-user-email': user2.email
}
})

expect(response.statusCode).toBe(401)
expect(response.json().message).toEqual(
`User with id ${user2.id} does not have the authority in the project with id ${project1.id}`
)
})

it('should not be able to fetch all variables by project and environment if the project does not exist', async () => {
const response = await app.inject({
method: 'GET',
url: `/variable/all/non-existing-project-id/${environment1.id}`,
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(404)
expect(response.json().message).toEqual(
'Project with id non-existing-project-id not found'
)
})

it('should not be able to fetch all variables by project and environment if the environment does not exist', async () => {
const response = await app.inject({
method: 'GET',
url: `/variable/all/${project1.id}/non-existing-environment-id`,
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(404)
})

it('should not be able to delete a non-existing variable', async () => {
const response = await app.inject({
method: 'DELETE',
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/commands/configure/configure.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default class ConfigureCommand implements BaseCommand {
intro('Configurations present: ')

const configurations = await fetchUserRootConfigurationFiles()
console.log(configurations)
Logger.info(configurations)
}

private async createConfiguration(parsedData) {
Expand Down

0 comments on commit 4396498

Please sign in to comment.