Skip to content

Commit

Permalink
feat(api): Add requireRestart parameter (#286)
Browse files Browse the repository at this point in the history
Signed-off-by: yogesh1801 <[email protected]>
  • Loading branch information
yogesh1801 authored and rajdip-b committed Jun 27, 2024
1 parent 76c40ca commit fb447a1
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "Secret" ADD COLUMN "requireRestart" BOOLEAN DEFAULT false;

-- AlterTable
ALTER TABLE "Variable" ADD COLUMN "requireRestart" BOOLEAN NOT NULL DEFAULT false;
28 changes: 15 additions & 13 deletions apps/api/src/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -358,13 +358,14 @@ model SecretVersion {
}

model Secret {
id String @id @default(cuid())
name String
versions SecretVersion[] // Stores the versions of the secret
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
rotateAt DateTime?
note String?
id String @id @default(cuid())
name String
versions SecretVersion[] // Stores the versions of the secret
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
rotateAt DateTime?
note String?
requireRestart Boolean @default(false)
lastUpdatedBy User? @relation(fields: [lastUpdatedById], references: [id], onUpdate: Cascade, onDelete: SetNull)
lastUpdatedById String?
Expand Down Expand Up @@ -394,12 +395,13 @@ model VariableVersion {
}

model Variable {
id String @id @default(cuid())
name String
versions VariableVersion[] // Stores the versions of the variable
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
note String?
id String @id @default(cuid())
name String
versions VariableVersion[] // Stores the versions of the variable
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
note String?
requireRestart Boolean @default(false)
lastUpdatedBy User? @relation(fields: [lastUpdatedById], references: [id], onUpdate: Cascade, onDelete: SetNull)
lastUpdatedById String?
Expand Down
6 changes: 6 additions & 0 deletions apps/api/src/secret/dto/create.secret/create.secret.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
IsArray,
IsOptional,
IsString,
IsBoolean,
Length,
ValidateNested
} from 'class-validator'
Expand All @@ -21,6 +22,11 @@ export class CreateSecret {
@IsOptional()
rotateAfter?: '24' | '168' | '720' | '8760' | 'never' = 'never'

@IsBoolean()
@IsOptional()
@Transform(({ value }) => value === 'true' || value === true)
requireRestart?: boolean

@IsOptional()
@IsArray()
@ValidateNested({ each: true })
Expand Down
58 changes: 58 additions & 0 deletions apps/api/src/secret/secret.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,40 @@ describe('Secret Controller Tests', () => {
expect(body.versions[0].value).not.toBe('Secret 2 value')
})

it('should be able to create a secret with requireRestart set to true', async () => {
const response = await app.inject({
method: 'POST',
url: `/secret/${project1.id}`,
payload: {
name: 'Secret 3',
note: 'Secret 3 note',
requireRestart: true,
entries: [
{
value: 'Secret 3 value',
environmentId: environment1.id
}
],
rotateAfter: '24'
},
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(201)

const body = response.json()

expect(body).toBeDefined()
expect(body.name).toBe('Secret 3')
expect(body.note).toBe('Secret 3 note')
expect(body.requireRestart).toBe(true)
expect(body.projectId).toBe(project1.id)
expect(body.versions.length).toBe(1)
expect(body.versions[0].value).not.toBe('Secret 3 value')
})

it('should have created a secret version', async () => {
const secretVersion = await prisma.secretVersion.findFirst({
where: {
Expand Down Expand Up @@ -343,6 +377,30 @@ describe('Secret Controller Tests', () => {
expect(secretVersion.length).toBe(1)
})

it('should be able to update the requireRestart Param without creating a new version', async () => {
const response = await app.inject({
method: 'PUT',
url: `/secret/${secret1.id}`,
payload: {
requireRestart: true
},
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(200)
expect(response.json().requireRestart).toEqual(true)

const secretVersion = await prisma.secretVersion.findMany({
where: {
secretId: secret1.id
}
})

expect(secretVersion.length).toBe(1)
})

it('should create a new version if the value is updated', async () => {
const response = await app.inject({
method: 'PUT',
Expand Down
4 changes: 4 additions & 0 deletions apps/api/src/secret/service/secret.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export class SecretService {
name: dto.name,
note: dto.note,
rotateAt: addHoursToDate(dto.rotateAfter),
requireRestart: dto.requireRestart,
versions: shouldCreateRevisions && {
createMany: {
data: await Promise.all(
Expand Down Expand Up @@ -198,6 +199,7 @@ export class SecretService {
data: {
name: dto.name,
note: dto.note,
requireRestart: dto.requireRestart,
rotateAt: dto.rotateAfter
? addHoursToDate(dto.rotateAfter)
: undefined,
Expand Down Expand Up @@ -268,6 +270,7 @@ export class SecretService {
environmentId: entry.environmentId,
name: updatedSecret.name,
value: entry.value,
requireRestart: dto.requireRestart,
isSecret: true
})
)
Expand Down Expand Up @@ -352,6 +355,7 @@ export class SecretService {
environmentId,
name: secret.name,
value: secret.versions[rollbackVersion - 1].value,
requireRestart: secret.requireRestart,
isSecret: true
})
)
Expand Down
1 change: 1 addition & 0 deletions apps/api/src/socket/socket.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface ChangeNotifierRegistration {
export interface ChangeNotification {
name: string
value: string
requireRestart: boolean
isSecret: boolean
}

Expand Down
6 changes: 6 additions & 0 deletions apps/api/src/variable/dto/create.variable/create.variable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
IsArray,
IsOptional,
IsString,
IsBoolean,
Length,
ValidateNested
} from 'class-validator'
Expand All @@ -19,6 +20,11 @@ export class CreateVariable {
@Transform(({ value }) => (value ? value.trim() : null))
note?: string

@IsBoolean()
@IsOptional()
@Transform(({ value }) => value === 'true' || value === true)
requireRestart?: boolean

@IsOptional()
@IsArray()
@ValidateNested({ each: true })
Expand Down
4 changes: 4 additions & 0 deletions apps/api/src/variable/service/variable.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export class VariableService {
data: {
name: dto.name,
note: dto.note,
requireRestart: dto.requireRestart,
versions: shouldCreateRevisions && {
createMany: {
data: dto.entries.map((entry) => ({
Expand Down Expand Up @@ -200,6 +201,7 @@ export class VariableService {
data: {
name: dto.name,
note: dto.note,
requireRestart: dto.requireRestart,
lastUpdatedById: user.id
},
include: {
Expand Down Expand Up @@ -266,6 +268,7 @@ export class VariableService {
environmentId: entry.environmentId,
name: updatedVariable.name,
value: entry.value,
requireRestart: dto.requireRestart,
isSecret: false
})
)
Expand Down Expand Up @@ -353,6 +356,7 @@ export class VariableService {
environmentId,
name: variable.name,
value: variable.versions[rollbackVersion - 1].value,
requireRestart: variable.requireRestart,
isSecret: false
})
)
Expand Down
66 changes: 66 additions & 0 deletions apps/api/src/variable/variable.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,48 @@ describe('Variable Controller Tests', () => {
expect(variable).toBeDefined()
})

it('should be able to create a variable with requireRestart set to true', async () => {
const response = await app.inject({
method: 'POST',
url: `/variable/${project1.id}`,
payload: {
name: 'Variable 4',
note: 'Variable 4 note',
requireRestart: true,
rotateAfter: '24',
entries: [
{
value: 'Variable 4 value',
environmentId: environment2.id
}
]
},
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(201)

const body = response.json()

expect(body).toBeDefined()
expect(body.name).toBe('Variable 4')
expect(body.note).toBe('Variable 4 note')
expect(body.requireRestart).toBe(true)
expect(body.projectId).toBe(project1.id)
expect(body.versions.length).toBe(1)
expect(body.versions[0].value).toBe('Variable 4 value')

const variable = await prisma.variable.findUnique({
where: {
id: body.id
}
})

expect(variable).toBeDefined()
})

it('should have created a variable version', async () => {
const variableVersion = await prisma.variableVersion.findFirst({
where: {
Expand Down Expand Up @@ -363,6 +405,30 @@ describe('Variable Controller Tests', () => {
expect(variableVersion.length).toBe(1)
})

it('should be able to update requireRestart param without creating a new version', async () => {
const response = await app.inject({
method: 'PUT',
url: `/variable/${variable1.id}`,
payload: {
requireRestart: true
},
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(200)
expect(response.json().requireRestart).toEqual(true)

const variableVersion = await prisma.variableVersion.findMany({
where: {
variableId: variable1.id
}
})

expect(variableVersion.length).toBe(1)
})

it('should create a new version if the value is updated', async () => {
const response = await app.inject({
method: 'PUT',
Expand Down
2 changes: 1 addition & 1 deletion apps/platform/src/lib/workspace-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ export function getCurrentWorkspace(): Workspace | null {

export function setCurrentWorkspace(workspace: Workspace): void {
localStorage.setItem('currentWorkspace', JSON.stringify(workspace))
}
}

0 comments on commit fb447a1

Please sign in to comment.