-
Notifications
You must be signed in to change notification settings - Fork 13
Secrets management tab #118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
b9fb98c
Remove TODOs and implement correct types in environmentDataSources.ts
kapicic feeaa0d
Add delete cascade to datasource properties
kapicic 34f4563
Add secrets management
kapicic add4c2d
Add all environments filter in the SecretsManagerTab.tsx
kapicic 5d94aca
Tidy edit environment variable form
kapicic 6b75354
Remove round dot prefix from environment variable name, style the dro…
kapicic 6e255a1
Merge branch 'dev' into stevan/eng-842
kapicic 0d91d83
Disable deleting data source secrets in secret manager
kapicic 1e74225
Get all environment variables instead of just per environment
kapicic 288425a
Add post body validator, replace console with logger
kapicic 6b14e9d
Merge branch 'dev' into stevan/eng-842
kapicic f0e9bf2
Update Add secret form
skosijer 8b344d5
Update Edit secrets form
skosijer 8fdd0cb
Fix input for secret key
skosijer e32dc6c
Remove comments
skosijer 1ea45b2
Merge branch 'dev' into stevan/eng-842
skosijer d2bb0c0
Show only global environment variables
skosijer 2ebc1f9
Enable editing environment id on environment variable
skosijer 92a6ff6
Remove console log
skosijer 0ecee62
Refactor the SecretsManagerTab fetch environments calls
skosijer 2a317ba
Add comment
skosijer 3684cfb
Refactor code based on PR comments
skosijer 068310f
Merge branch 'dev' into stevank/eng-940
skosijer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| import { NextRequest, NextResponse } from 'next/server'; | ||
| import { requireUserAbility } from '~/auth/session'; | ||
| import { prisma } from '~/lib/prisma'; | ||
| import { deleteEnvironmentVariable, updateEnvironmentVariable } from '~/lib/services/environmentVariablesService'; | ||
| import { logger } from '~/utils/logger'; | ||
| import { PermissionAction, PermissionResource } from '@prisma/client'; | ||
|
|
||
| export async function PUT(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { | ||
| try { | ||
| const { userAbility } = await requireUserAbility(request); | ||
|
|
||
| const { id } = await params; | ||
|
|
||
| if (!userAbility.can(PermissionAction.update, PermissionResource.EnvironmentVariable)) { | ||
| return NextResponse.json({ success: false, error: 'Forbidden' }, { status: 403 }); | ||
| } | ||
|
|
||
| const body = (await request.json()) as { | ||
| key: string; | ||
| environmentId: string; | ||
| value: string; | ||
| type: string; | ||
| description?: string; | ||
| }; | ||
|
|
||
| const { key, environmentId, value, type, description } = body; | ||
|
|
||
| if (!key || !value || !type) { | ||
| return NextResponse.json({ success: false, error: 'Missing required fields: key, value, type' }, { status: 400 }); | ||
| } | ||
|
|
||
| // Check if user has access to this environment variable | ||
| const envVar = await prisma.environmentVariable.findUnique({ | ||
| where: { id }, | ||
| include: { | ||
| environment: true, | ||
| }, | ||
| }); | ||
|
|
||
| if (!envVar) { | ||
| return NextResponse.json({ success: false, error: 'Environment variable not found' }, { status: 404 }); | ||
| } | ||
|
|
||
| if (!userAbility.can(PermissionAction.read, PermissionResource.Environment)) { | ||
| return NextResponse.json( | ||
| { success: false, error: 'Access denied to this environment variable' }, | ||
| { status: 403 }, | ||
| ); | ||
|
skosijer marked this conversation as resolved.
|
||
| } | ||
|
|
||
| // Check if key already exists for this environment (excluding current env var) | ||
| const existingEnvVar = await prisma.environmentVariable.findFirst({ | ||
| where: { | ||
| key, | ||
| environmentId: environmentId || envVar.environmentId, | ||
| id: { not: id }, | ||
| }, | ||
| }); | ||
|
|
||
| if (existingEnvVar) { | ||
| return NextResponse.json( | ||
| { success: false, error: 'Environment variable with this key already exists' }, | ||
| { status: 409 }, | ||
| ); | ||
| } | ||
|
|
||
| const updatedEnvironmentVariable = await updateEnvironmentVariable( | ||
| id, | ||
| key, | ||
| value, | ||
| type as any, // Type will be validated by the service | ||
| environmentId || envVar.environmentId, | ||
| description, | ||
| ); | ||
|
|
||
| return NextResponse.json({ | ||
| success: true, | ||
| environmentVariable: updatedEnvironmentVariable, | ||
| }); | ||
| } catch (error) { | ||
| logger.error('Failed to update environment variable:', error); | ||
| return NextResponse.json({ success: false, error: 'Failed to update environment variable' }, { status: 500 }); | ||
| } | ||
| } | ||
|
|
||
| export async function DELETE(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { | ||
| try { | ||
| const { userAbility } = await requireUserAbility(request); | ||
|
|
||
| const { id } = await params; | ||
|
|
||
| if (!userAbility.can(PermissionAction.delete, PermissionResource.EnvironmentVariable)) { | ||
| return NextResponse.json({ success: false, error: 'Forbidden' }, { status: 403 }); | ||
| } | ||
|
|
||
| // Check if user has access to this environment variable | ||
| const envVar = await prisma.environmentVariable.findUnique({ | ||
| where: { id }, | ||
| include: { | ||
| environment: true, | ||
| }, | ||
| }); | ||
|
|
||
| if (!envVar) { | ||
| return NextResponse.json({ success: false, error: 'Environment variable not found' }, { status: 404 }); | ||
| } | ||
|
|
||
| if (!userAbility.can(PermissionAction.read, PermissionResource.Environment)) { | ||
| return NextResponse.json( | ||
| { success: false, error: 'Access denied to this environment variable' }, | ||
| { status: 403 }, | ||
| ); | ||
| } | ||
|
|
||
| await deleteEnvironmentVariable(id); | ||
|
|
||
| return NextResponse.json({ | ||
| success: true, | ||
| }); | ||
| } catch (error) { | ||
| logger.error('Failed to delete environment variable:', error); | ||
| return NextResponse.json({ success: false, error: 'Failed to delete environment variable' }, { status: 500 }); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| import { NextRequest, NextResponse } from 'next/server'; | ||
| import { requireUserAbility } from '~/auth/session'; | ||
| import { | ||
| createEnvironmentVariable, | ||
| getEnvironmentVariablesWithEnvironmentDetails, | ||
| } from '~/lib/services/environmentVariablesService'; | ||
| import { logger } from '~/utils/logger'; | ||
| import { type EnvironmentVariableType, PermissionAction, PermissionResource } from '@prisma/client'; | ||
| import { z } from 'zod'; | ||
|
|
||
| const postBodySchema = z.object({ | ||
| key: z.string().min(1), | ||
| value: z.string().min(1), | ||
| type: z.enum(['GLOBAL', 'DATA_SOURCE']), | ||
| environmentId: z.string().min(1), | ||
| description: z.string().optional(), | ||
| }); | ||
|
|
||
| export async function GET(request: NextRequest) { | ||
| try { | ||
| const { searchParams } = new URL(request.url); | ||
| const environmentId = searchParams.get('environmentId'); | ||
| const type = searchParams.get('type') as EnvironmentVariableType | null; | ||
|
|
||
| // Check if user has permission to read environment variables | ||
| const { userAbility } = await requireUserAbility(request); | ||
|
|
||
| if (!userAbility.can(PermissionAction.read, PermissionResource.EnvironmentVariable)) { | ||
| return NextResponse.json( | ||
| { success: false, error: 'Insufficient permissions to read environment variables' }, | ||
| { status: 403 }, | ||
| ); | ||
| } | ||
|
|
||
| if (!environmentId) { | ||
| return NextResponse.json({ success: false, error: 'Environment ID is required' }, { status: 400 }); | ||
| } | ||
|
|
||
| const environmentVariables = await getEnvironmentVariablesWithEnvironmentDetails(environmentId, type); | ||
|
|
||
| return NextResponse.json({ | ||
| success: true, | ||
| environmentVariables, | ||
| }); | ||
| } catch (error) { | ||
| logger.error('Failed to fetch environment variables:', error); | ||
| return NextResponse.json({ success: false, error: 'Failed to fetch environment variables' }, { status: 500 }); | ||
| } | ||
| } | ||
|
|
||
| export async function POST(request: NextRequest) { | ||
| try { | ||
| const { userId, userAbility } = await requireUserAbility(request); | ||
|
|
||
| if (!userAbility.can(PermissionAction.create, PermissionResource.EnvironmentVariable)) { | ||
| return NextResponse.json({ success: false, error: 'Forbidden' }, { status: 403 }); | ||
| } | ||
|
|
||
| const body = postBodySchema.parse(await request.json()); | ||
|
|
||
| const { key, value, type, environmentId, description } = body; | ||
|
|
||
| // Check if user has access to this environment | ||
| if (!userAbility.can(PermissionAction.read, PermissionResource.Environment)) { | ||
| return NextResponse.json({ success: false, error: 'Access denied to this environment' }, { status: 403 }); | ||
| } | ||
|
skosijer marked this conversation as resolved.
|
||
|
|
||
| // Check if environment variable with this key already exists | ||
| const existingEnvVar = await prisma.environmentVariable.findUnique({ | ||
| where: { | ||
| key_environmentId: { | ||
| key, | ||
| environmentId, | ||
| }, | ||
| }, | ||
| }); | ||
|
|
||
| if (existingEnvVar) { | ||
| return NextResponse.json( | ||
| { success: false, error: 'Environment variable with this key already exists' }, | ||
| { status: 409 }, | ||
| ); | ||
| } | ||
|
|
||
| const environmentVariable = await createEnvironmentVariable( | ||
| key, | ||
| value, | ||
| type as EnvironmentVariableType, | ||
| environmentId, | ||
| userId, | ||
| description, | ||
| ); | ||
|
|
||
| return NextResponse.json({ | ||
| success: true, | ||
| environmentVariable, | ||
| }); | ||
| } catch (error) { | ||
| logger.error('Failed to create environment variable:', error); | ||
| return NextResponse.json({ success: false, error: 'Failed to create environment variable' }, { status: 500 }); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.