diff --git a/README.md b/README.md index 941d50c34..723bca2d7 100644 --- a/README.md +++ b/README.md @@ -4,35 +4,38 @@ Phase - Website | - Documentation | - Security | - Contributing | - Join Slack +
Repos
+

+ Docs | + CLI | + Node SDK | + Python SDK +
+ Golang SDK | + Helm Chart | + Kubernetes Operator | + Terraform Provider +

--- -Open source platform for fast-moving engineering teams to secure and deploy application secrets — from development to production. - -A developer-friendly alternative to **HashiCorp Vault** and **AWS Secrets Manager** that works with your whole team 🧑‍💻. - +#### Open source platform for fast-moving engineering teams to secure and deploy application secrets — from development to production. --- -# Phase Console -https://github.com/user-attachments/assets/160c721d-a941-440a-bc42-afd419c1df18 - +[Phase Console Demo](https://github.com/user-attachments/assets/cd6b1ffe-6cb4-4a2b-8ae1-9daa61ed3a5a) | | **Features** | | --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | 📈 | **[Phase Console](https://console.phase.dev)**: Dashboard for seamlessly creating, managing, rotating secrets, and environment variables | -| ⌨️ | **[CLI](https://github.com/phasehq/cli)**: Import existing secrets from `.env` files, encrypt them, and securely inject them in your application at runtime | -| 🤫 | **[Secret management](https://docs.phase.dev/console/apps)**: Secret Diffs, version control, and recovery | -| 🙋 | **[RBAC](https://docs.phase.dev/console/users#user-roles)**: Fine-grained, role-based, and cryptographic access control, per application, per environment. | -| 🔌 | **[Integrations](https://docs.phase.dev/#integrate-phase)**: Automatically sync secrets to GitHub, Cloudflare Pages, GitLab CI, Railway, AWS Secrets Manager, etc. | -| ![Kubernetes](img/kubernetes.svg) | **[Kubernetes](https://docs.phase.dev/integrations/platforms/kubernetes)**: Automatically deploy secrets to your Kubernetes Cluster with End-to-End encryption via Phase Secrets Operator | -| ⛓️ | **[Secret referencing & overrides](https://docs.phase.dev/console/secrets)**: Create personal secrets. Inherit values from other secrets | -| 🌐 | **[REST API](https://docs.phase.dev/public-api/secrets#get-secrets)**: Access and manage secrets programmatically | +| ⌨️ | **[CLI](https://github.com/phasehq/cli)**: Import existing secrets from `.env` files, and securely inject them in your application at runtime or create virtual shells with secrets | +| 🤫 | **[Secret management](https://docs.phase.dev/console/apps)**: Manage secrets across environments, view secret diffs, track version history, and restore secret values with a single click | +| 🙋 | **[Role-based Access Control](https://docs.phase.dev/console/users#user-roles)**: Fine-grained, role-based, and cryptographic access control, per application, per environment. | +| 🔁 | **[Secret sync](https://docs.phase.dev/#integrate-phase)**: Automatically sync secrets to GitHub, Cloudflare Pages, Vercel, GitLab CI, Railway, AWS Secrets Manager, etc. | +| ![Kubernetes](img/kubernetes.svg) | **[Kubernetes](https://docs.phase.dev/integrations/platforms/kubernetes)**: Automatically sync secrets to your Kubernetes Cluster and reload deployments via the Phase Secrets Operator | +| ![Terraform Provider](img/terraform.svg) | **[Terraform](https://docs.phase.dev/integrations/platforms/hashicorp-terraform)**: Manage secrets in your HashiCorp Terraform Iac workflows. | +| ⛓️ | **[Secret referencing & overrides](https://docs.phase.dev/console/secrets)**: Create personal secrets without affecting others on the team. Reference secret values across apps and environments | +| 🌐 | **[REST API](https://docs.phase.dev/public-api/secrets#get-secrets)**: Access and manage secrets programmatically with any http client | | 📦 | **[SDKs](https://docs.phase.dev/sdks)**: SDKs for integrating Phase with various programming languages and frameworks | 🥡 | **[Self Hosting](https://docs.phase.dev)**: Run Phase on your own infrastructure | | 🔍 | **[Audit Logs]()**: Complete visibility into every change and access event | | | @@ -41,42 +44,33 @@ https://github.com/user-attachments/assets/160c721d-a941-440a-bc42-afd419c1df18 --- -## CLI - Import, Encrypt and Inject secrets - -![Phase CI](img/phase-cli-import-run.webp) +## CLI ```fish -λ phase +λ phase --help Securely manage application secrets and environment variables with Phase. - @@@ - @@@@@@@@@@ - @@@@@@@@@@@@@@@@ - P@@@@@&@@@?&@@&@@@@@P - P@@@@# @&@ @P@@@ - &@@@# *@& #@@@& - &@@@5 &@? 5@@@& - Y@@@# ^@@ #@@@J - #@@@7 B@5 7@@@# - #@@@? .@@. ?@@@# - @@@@& 5@G &@@@7 - #@@@B @@^ #@@@B - B@@@@ .@# 7@@@@B - @@@@@@ &.@ P@@@@@7 - @@@@@@@@@@@@@@@@@@@@@ - @@@@@@@@@@@@@@@ - @@@@@@@@ - @@@ + /$$ + | $$ + /$$$$$$ | $$$$$$$ /$$$$$$ /$$$$$$$ /$$$$$$ + /$$__ $$| $$__ $$ |____ $$ /$$_____/ /$$__ $$ +| $$ \ $$| $$ \ $$ /$$$$$$$| $$$$$$ | $$$$$$$$ +| $$ | $$| $$ | $$ /$$__ $$ \____ $$| $$_____/ +| $$$$$$$/| $$ | $$| $$$$$$$ /$$$$$$$/| $$$$$$$ +| $$____/ |__/ |__/ \_______/|_______/ \_______/ +| $$ +|__/ options: -h, --help show this help message and exit --version, -v show program's version number and exit - Commands: + auth 💻 Authenticate with Phase init 🔗 Link your project with your Phase app run 🚀 Run and inject secrets to your app + shell 🐚 Launch a sub-shell with secrets as environment variables (BETA) secrets 🗝️ Manage your secrets secrets list 📇 List all the secrets secrets get 🔍 Get a specific secret by key @@ -87,6 +81,7 @@ Commands: secrets export 🥡 Export secrets in a dotenv format users 👥 Manage users and accounts users whoami 🙋 See details of the current user + users switch 🪄 Switch between Phase users, orgs and hosts users logout 🏃 Logout from phase-cli users keyring 🔐 Display information about the Phase keyring docs 📖 Open the Phase CLI Docs in your browser @@ -111,7 +106,9 @@ The quickest and most reliable way to get started is by signing up on the [Phase | | **Deploy Phase Console on your infrastructure** | | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | |![Docker](img/docker.svg) | [Docker Compose](https://docs.phase.dev/self-hosting/docker-compose) | +|![Kubernetes](img/kubernetes.svg) | [Kubernetes (Helm chart)](https://docs.phase.dev/self-hosting/kubernetes) | |![AWS](img/aws.svg) | [AWS](https://docs.phase.dev/self-hosting/aws) | +|![AWS EKS](img/aws-eks.svg) | [AWS EKS (Helm chart)](https://docs.phase.dev/self-hosting/aws-eks) | |![GCP](img/gcp.svg) | [Google Cloud Platform](https://docs.phase.dev/self-hosting/gcp) | |![Azure](img/azure.svg) | [Azure](https://docs.phase.dev/self-hosting/azure) | |![DigitalOcean](img/do.svg) | [DigitalOcean](https://docs.phase.dev/self-hosting/digitalocean) | diff --git a/backend/backend/graphene/types.py b/backend/backend/graphene/types.py index 1e8f534f7..b4eb322c4 100644 --- a/backend/backend/graphene/types.py +++ b/backend/backend/graphene/types.py @@ -171,7 +171,7 @@ class OrganisationMemberType(DjangoObjectType): role = graphene.Field(RoleType) self = graphene.Boolean() last_login = graphene.DateTime() - app_memberships = graphene.List(graphene.NonNull(lambda: AppType)) + app_memberships = graphene.List(graphene.NonNull(lambda: AppMembershipType)) tokens = graphene.List(graphene.NonNull(lambda: UserTokenType)) network_policies = graphene.List(graphene.NonNull(lambda: NetworkAccessPolicyType)) @@ -497,7 +497,10 @@ def resolve_override(self, info): class EnvironmentType(DjangoObjectType): folders = graphene.NonNull(graphene.List(SecretFolderType)) - secrets = graphene.NonNull(graphene.List(SecretType)) + secrets = graphene.NonNull( + graphene.List(SecretType), + path=graphene.String(required=False) + ) folder_count = graphene.Int() secret_count = graphene.Int() members = graphene.NonNull(graphene.List(OrganisationMemberType)) @@ -520,7 +523,7 @@ class Meta: "updated_at", ) - def resolve_secrets(self, info, path="/"): + def resolve_secrets(self, info, path=None): org = self.app.organisation if not user_has_permission( @@ -535,11 +538,12 @@ def resolve_secrets(self, info, path="/"): filter = {"environment": self, "deleted_at": None} - if path: + if path is not None: filter["path"] = path return Secret.objects.filter(**filter).order_by("-created_at") + def resolve_folders(self, info, path=None): if not user_can_access_environment(info.context.user.userId, self.id): raise GraphQLError("You don't have access to this environment") @@ -655,13 +659,29 @@ def resolve_updated_at(self, info): def resolve_members(self, info): return self.members.filter(deleted_at=None) +class AppMembershipType(DjangoObjectType): + environments = graphene.NonNull(graphene.List(EnvironmentType)) + + class Meta: + model = App + fields = ( + "id", + "name", + "sse_enabled", + ) + + def resolve_environments(self, info): + # Only return filtered environments if set + return getattr(self, "filtered_environments", []) + + class ServiceAccountType(DjangoObjectType): third_party_auth_enabled = graphene.Boolean() handlers = graphene.List(ServiceAccountHandlerType) tokens = graphene.List(ServiceAccountTokenType) - app_memberships = graphene.List(graphene.NonNull(AppType)) + app_memberships = graphene.List(graphene.NonNull(AppMembershipType)) network_policies = graphene.List(graphene.NonNull(lambda: NetworkAccessPolicyType)) class Meta: diff --git a/backend/backend/schema.py b/backend/backend/schema.py index 5f76124b8..2b3dc8813 100644 --- a/backend/backend/schema.py +++ b/backend/backend/schema.py @@ -228,8 +228,8 @@ class Query(graphene.ObjectType): organisation_members = graphene.List( OrganisationMemberType, organisation_id=graphene.ID(), - user_id=graphene.ID(), - role=graphene.List(graphene.String), + member_id=graphene.ID(required=False), + role=graphene.List(graphene.String, required=False), ) organisation_global_access_users = graphene.List( OrganisationMemberType, organisation_id=graphene.ID() @@ -440,13 +440,16 @@ def resolve_organisation_name_available(root, info, name): resolve_license = resolve_license resolve_organisation_license = resolve_organisation_license - def resolve_organisation_members(root, info, organisation_id, role, user_id=None): + def resolve_organisation_members(root, info, organisation_id, role = None, member_id=None): if not user_is_org_member(info.context.user.userId, organisation_id): raise GraphQLError("You don't have access to this organisation") filter = {"organisation_id": organisation_id, "deleted_at": None} - if role: + if member_id is not None: + filter["id"] = member_id + + if role is not None: roles = [user_role.lower() for user_role in role] filter["roles__in"] = roles diff --git a/backend/version.txt b/backend/version.txt index aeb5aaff2..fc6e41f19 100644 --- a/backend/version.txt +++ b/backend/version.txt @@ -1 +1 @@ -v2.46.0 +v2.47.0 diff --git a/frontend/apollo/gql.ts b/frontend/apollo/gql.ts index bedb7696f..b8dedebb4 100644 --- a/frontend/apollo/gql.ts +++ b/frontend/apollo/gql.ts @@ -105,16 +105,17 @@ const documents = { "query GetInvites($orgId: ID!) {\n organisationInvites(orgId: $orgId) {\n id\n createdAt\n expiresAt\n invitedBy {\n email\n fullName\n self\n }\n inviteeEmail\n role {\n id\n name\n description\n color\n }\n }\n}": types.GetInvitesDocument, "query GetLicenseData {\n license {\n id\n customerName\n organisationName\n expiresAt\n plan\n seats\n isActivated\n organisationOwner {\n fullName\n email\n }\n }\n}": types.GetLicenseDataDocument, "query GetOrgLicense($organisationId: ID!) {\n organisationLicense(organisationId: $organisationId) {\n id\n customerName\n issuedAt\n expiresAt\n activatedAt\n plan\n seats\n tokens\n }\n}": types.GetOrgLicenseDocument, - "query GetOrganisationMembers($organisationId: ID!, $role: [String]) {\n organisationMembers(organisationId: $organisationId, role: $role) {\n id\n role {\n id\n name\n description\n permissions\n color\n }\n identityKey\n email\n fullName\n avatarUrl\n createdAt\n lastLogin\n self\n appMemberships {\n id\n name\n sseEnabled\n environments {\n id\n name\n }\n }\n tokens {\n id\n name\n createdAt\n expiresAt\n }\n networkPolicies {\n id\n name\n allowedIps\n isGlobal\n }\n }\n}": types.GetOrganisationMembersDocument, + "query GetOrganisationMembers($organisationId: ID!, $role: [String]) {\n organisationMembers(organisationId: $organisationId, role: $role) {\n id\n role {\n id\n name\n description\n permissions\n color\n }\n identityKey\n email\n fullName\n avatarUrl\n createdAt\n lastLogin\n self\n }\n}": types.GetOrganisationMembersDocument, "query GetOrganisationPlan($organisationId: ID!) {\n organisationPlan(organisationId: $organisationId) {\n name\n maxUsers\n maxApps\n maxEnvsPerApp\n seatsUsed {\n users\n serviceAccounts\n total\n }\n seatLimit\n appCount\n }\n}": types.GetOrganisationPlanDocument, "query GetRoles($orgId: ID!) {\n roles(orgId: $orgId) {\n id\n name\n description\n color\n permissions\n isDefault\n }\n}": types.GetRolesDocument, "query VerifyInvite($inviteId: ID!) {\n validateInvite(inviteId: $inviteId) {\n id\n organisation {\n id\n name\n }\n inviteeEmail\n invitedBy {\n fullName\n email\n }\n apps {\n id\n name\n }\n }\n}": types.VerifyInviteDocument, "query GetAppEnvironments($appId: ID!, $memberId: ID, $memberType: MemberType) {\n appEnvironments(\n appId: $appId\n environmentId: null\n memberId: $memberId\n memberType: $memberType\n ) {\n id\n name\n envType\n identityKey\n wrappedSeed\n wrappedSalt\n createdAt\n app {\n name\n id\n }\n secretCount\n folderCount\n index\n members {\n email\n fullName\n avatarUrl\n }\n }\n sseEnabled(appId: $appId)\n serverPublicKey\n}": types.GetAppEnvironmentsDocument, - "query GetAppSecrets($appId: ID!, $memberId: ID, $memberType: MemberType) {\n appEnvironments(\n appId: $appId\n environmentId: null\n memberId: $memberId\n memberType: $memberType\n ) {\n id\n name\n envType\n identityKey\n wrappedSeed\n wrappedSalt\n createdAt\n app {\n name\n id\n }\n secretCount\n folderCount\n index\n members {\n email\n fullName\n avatarUrl\n }\n folders {\n id\n name\n path\n }\n secrets {\n id\n key\n value\n comment\n path\n }\n }\n sseEnabled(appId: $appId)\n serverPublicKey\n}": types.GetAppSecretsDocument, + "query GetAppSecrets($appId: ID!, $memberId: ID, $memberType: MemberType, $path: String) {\n appEnvironments(\n appId: $appId\n environmentId: null\n memberId: $memberId\n memberType: $memberType\n ) {\n id\n name\n envType\n identityKey\n wrappedSeed\n wrappedSalt\n createdAt\n app {\n name\n id\n }\n secretCount\n folderCount\n index\n members {\n email\n fullName\n avatarUrl\n }\n folders {\n id\n name\n path\n }\n secrets(path: $path) {\n id\n key\n value\n comment\n path\n }\n }\n sseEnabled(appId: $appId)\n serverPublicKey\n}": types.GetAppSecretsDocument, "query GetAppSecretsLogs($appId: ID!, $start: BigInt, $end: BigInt, $eventTypes: [String], $memberId: ID, $memberType: MemberType, $environmentId: ID) {\n secretLogs(\n appId: $appId\n start: $start\n end: $end\n eventTypes: $eventTypes\n memberId: $memberId\n memberType: $memberType\n environmentId: $environmentId\n ) {\n logs {\n id\n path\n key\n value\n tags {\n id\n name\n color\n }\n version\n comment\n timestamp\n ipAddress\n userAgent\n user {\n email\n username\n fullName\n avatarUrl\n }\n serviceToken {\n id\n name\n }\n serviceAccount {\n id\n name\n }\n serviceAccountToken {\n id\n name\n }\n eventType\n environment {\n id\n envType\n name\n }\n secret {\n id\n path\n }\n }\n count\n }\n environmentKeys(appId: $appId) {\n id\n identityKey\n wrappedSeed\n wrappedSalt\n environment {\n id\n }\n }\n}": types.GetAppSecretsLogsDocument, "query GetEnvironmentKey($envId: ID!, $appId: ID!) {\n environmentKeys(environmentId: $envId, appId: $appId) {\n id\n identityKey\n wrappedSeed\n wrappedSalt\n }\n}": types.GetEnvironmentKeyDocument, "query GetEnvironmentTokens($envId: ID!) {\n environmentTokens(environmentId: $envId) {\n id\n name\n wrappedKeyShare\n createdAt\n }\n}": types.GetEnvironmentTokensDocument, "query GetFolders($envId: ID!, $path: String) {\n folders(envId: $envId, path: $path) {\n id\n name\n path\n createdAt\n folderCount\n secretCount\n }\n}": types.GetFoldersDocument, + "query GetOrgSecretKeys($organisationId: ID!) {\n apps(organisationId: $organisationId) {\n id\n name\n environments {\n id\n name\n wrappedSeed\n wrappedSalt\n secrets {\n id\n key\n path\n }\n }\n }\n}": types.GetOrgSecretKeysDocument, "query GetSecretHistory($appId: ID!, $envId: ID!, $id: ID!) {\n secrets(envId: $envId, id: $id) {\n id\n history {\n id\n key\n value\n path\n tags {\n id\n name\n color\n }\n version\n comment\n timestamp\n ipAddress\n userAgent\n user {\n email\n username\n fullName\n avatarUrl\n }\n serviceToken {\n id\n name\n }\n serviceAccount {\n id\n name\n }\n eventType\n }\n }\n environmentKeys(appId: $appId, environmentId: $envId) {\n id\n identityKey\n wrappedSeed\n wrappedSalt\n }\n}": types.GetSecretHistoryDocument, "query GetEnvSecretsKV($envId: ID!) {\n folders(envId: $envId, path: \"/\") {\n id\n name\n }\n secrets(envId: $envId, path: \"/\") {\n id\n key\n value\n comment\n path\n }\n environmentKeys(environmentId: $envId) {\n id\n identityKey\n wrappedSeed\n wrappedSalt\n }\n}": types.GetEnvSecretsKvDocument, "query GetSecretTags($orgId: ID!) {\n secretTags(orgId: $orgId) {\n id\n name\n color\n }\n}": types.GetSecretTagsDocument, @@ -140,6 +141,7 @@ const documents = { "query GetRailwayProjects($credentialId: ID!) {\n railwayProjects(credentialId: $credentialId) {\n id\n name\n environments {\n id\n name\n }\n services {\n id\n name\n }\n }\n}": types.GetRailwayProjectsDocument, "query TestVaultAuth($credentialId: ID!) {\n testVaultCreds(credentialId: $credentialId)\n}": types.TestVaultAuthDocument, "query GetVercelProjects($credentialId: ID!) {\n vercelProjects(credentialId: $credentialId) {\n id\n teamName\n projects {\n id\n name\n environment\n }\n }\n}": types.GetVercelProjectsDocument, + "query GetOrganisationMemberDetail($organisationId: ID!, $id: ID) {\n organisationMembers(organisationId: $organisationId, memberId: $id) {\n id\n role {\n id\n name\n description\n permissions\n color\n }\n identityKey\n email\n fullName\n avatarUrl\n createdAt\n lastLogin\n self\n appMemberships {\n id\n name\n sseEnabled\n environments {\n id\n name\n }\n }\n tokens {\n id\n name\n createdAt\n expiresAt\n }\n networkPolicies {\n id\n name\n allowedIps\n isGlobal\n }\n }\n}": types.GetOrganisationMemberDetailDocument, "query GetUserTokens($organisationId: ID!) {\n userTokens(organisationId: $organisationId) {\n id\n name\n wrappedKeyShare\n createdAt\n expiresAt\n }\n}": types.GetUserTokensDocument, }; @@ -528,7 +530,7 @@ export function graphql(source: "query GetOrgLicense($organisationId: ID!) {\n /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "query GetOrganisationMembers($organisationId: ID!, $role: [String]) {\n organisationMembers(organisationId: $organisationId, role: $role) {\n id\n role {\n id\n name\n description\n permissions\n color\n }\n identityKey\n email\n fullName\n avatarUrl\n createdAt\n lastLogin\n self\n appMemberships {\n id\n name\n sseEnabled\n environments {\n id\n name\n }\n }\n tokens {\n id\n name\n createdAt\n expiresAt\n }\n networkPolicies {\n id\n name\n allowedIps\n isGlobal\n }\n }\n}"): (typeof documents)["query GetOrganisationMembers($organisationId: ID!, $role: [String]) {\n organisationMembers(organisationId: $organisationId, role: $role) {\n id\n role {\n id\n name\n description\n permissions\n color\n }\n identityKey\n email\n fullName\n avatarUrl\n createdAt\n lastLogin\n self\n appMemberships {\n id\n name\n sseEnabled\n environments {\n id\n name\n }\n }\n tokens {\n id\n name\n createdAt\n expiresAt\n }\n networkPolicies {\n id\n name\n allowedIps\n isGlobal\n }\n }\n}"]; +export function graphql(source: "query GetOrganisationMembers($organisationId: ID!, $role: [String]) {\n organisationMembers(organisationId: $organisationId, role: $role) {\n id\n role {\n id\n name\n description\n permissions\n color\n }\n identityKey\n email\n fullName\n avatarUrl\n createdAt\n lastLogin\n self\n }\n}"): (typeof documents)["query GetOrganisationMembers($organisationId: ID!, $role: [String]) {\n organisationMembers(organisationId: $organisationId, role: $role) {\n id\n role {\n id\n name\n description\n permissions\n color\n }\n identityKey\n email\n fullName\n avatarUrl\n createdAt\n lastLogin\n self\n }\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -548,7 +550,7 @@ export function graphql(source: "query GetAppEnvironments($appId: ID!, $memberId /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "query GetAppSecrets($appId: ID!, $memberId: ID, $memberType: MemberType) {\n appEnvironments(\n appId: $appId\n environmentId: null\n memberId: $memberId\n memberType: $memberType\n ) {\n id\n name\n envType\n identityKey\n wrappedSeed\n wrappedSalt\n createdAt\n app {\n name\n id\n }\n secretCount\n folderCount\n index\n members {\n email\n fullName\n avatarUrl\n }\n folders {\n id\n name\n path\n }\n secrets {\n id\n key\n value\n comment\n path\n }\n }\n sseEnabled(appId: $appId)\n serverPublicKey\n}"): (typeof documents)["query GetAppSecrets($appId: ID!, $memberId: ID, $memberType: MemberType) {\n appEnvironments(\n appId: $appId\n environmentId: null\n memberId: $memberId\n memberType: $memberType\n ) {\n id\n name\n envType\n identityKey\n wrappedSeed\n wrappedSalt\n createdAt\n app {\n name\n id\n }\n secretCount\n folderCount\n index\n members {\n email\n fullName\n avatarUrl\n }\n folders {\n id\n name\n path\n }\n secrets {\n id\n key\n value\n comment\n path\n }\n }\n sseEnabled(appId: $appId)\n serverPublicKey\n}"]; +export function graphql(source: "query GetAppSecrets($appId: ID!, $memberId: ID, $memberType: MemberType, $path: String) {\n appEnvironments(\n appId: $appId\n environmentId: null\n memberId: $memberId\n memberType: $memberType\n ) {\n id\n name\n envType\n identityKey\n wrappedSeed\n wrappedSalt\n createdAt\n app {\n name\n id\n }\n secretCount\n folderCount\n index\n members {\n email\n fullName\n avatarUrl\n }\n folders {\n id\n name\n path\n }\n secrets(path: $path) {\n id\n key\n value\n comment\n path\n }\n }\n sseEnabled(appId: $appId)\n serverPublicKey\n}"): (typeof documents)["query GetAppSecrets($appId: ID!, $memberId: ID, $memberType: MemberType, $path: String) {\n appEnvironments(\n appId: $appId\n environmentId: null\n memberId: $memberId\n memberType: $memberType\n ) {\n id\n name\n envType\n identityKey\n wrappedSeed\n wrappedSalt\n createdAt\n app {\n name\n id\n }\n secretCount\n folderCount\n index\n members {\n email\n fullName\n avatarUrl\n }\n folders {\n id\n name\n path\n }\n secrets(path: $path) {\n id\n key\n value\n comment\n path\n }\n }\n sseEnabled(appId: $appId)\n serverPublicKey\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -565,6 +567,10 @@ export function graphql(source: "query GetEnvironmentTokens($envId: ID!) {\n en * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "query GetFolders($envId: ID!, $path: String) {\n folders(envId: $envId, path: $path) {\n id\n name\n path\n createdAt\n folderCount\n secretCount\n }\n}"): (typeof documents)["query GetFolders($envId: ID!, $path: String) {\n folders(envId: $envId, path: $path) {\n id\n name\n path\n createdAt\n folderCount\n secretCount\n }\n}"]; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "query GetOrgSecretKeys($organisationId: ID!) {\n apps(organisationId: $organisationId) {\n id\n name\n environments {\n id\n name\n wrappedSeed\n wrappedSalt\n secrets {\n id\n key\n path\n }\n }\n }\n}"): (typeof documents)["query GetOrgSecretKeys($organisationId: ID!) {\n apps(organisationId: $organisationId) {\n id\n name\n environments {\n id\n name\n wrappedSeed\n wrappedSalt\n secrets {\n id\n key\n path\n }\n }\n }\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -665,6 +671,10 @@ export function graphql(source: "query TestVaultAuth($credentialId: ID!) {\n te * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "query GetVercelProjects($credentialId: ID!) {\n vercelProjects(credentialId: $credentialId) {\n id\n teamName\n projects {\n id\n name\n environment\n }\n }\n}"): (typeof documents)["query GetVercelProjects($credentialId: ID!) {\n vercelProjects(credentialId: $credentialId) {\n id\n teamName\n projects {\n id\n name\n environment\n }\n }\n}"]; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "query GetOrganisationMemberDetail($organisationId: ID!, $id: ID) {\n organisationMembers(organisationId: $organisationId, memberId: $id) {\n id\n role {\n id\n name\n description\n permissions\n color\n }\n identityKey\n email\n fullName\n avatarUrl\n createdAt\n lastLogin\n self\n appMemberships {\n id\n name\n sseEnabled\n environments {\n id\n name\n }\n }\n tokens {\n id\n name\n createdAt\n expiresAt\n }\n networkPolicies {\n id\n name\n allowedIps\n isGlobal\n }\n }\n}"): (typeof documents)["query GetOrganisationMemberDetail($organisationId: ID!, $id: ID) {\n organisationMembers(organisationId: $organisationId, memberId: $id) {\n id\n role {\n id\n name\n description\n permissions\n color\n }\n identityKey\n email\n fullName\n avatarUrl\n createdAt\n lastLogin\n self\n appMemberships {\n id\n name\n sseEnabled\n environments {\n id\n name\n }\n }\n tokens {\n id\n name\n createdAt\n expiresAt\n }\n networkPolicies {\n id\n name\n allowedIps\n isGlobal\n }\n }\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/frontend/apollo/graphql.ts b/frontend/apollo/graphql.ts index ba2429e08..caf23224b 100644 --- a/frontend/apollo/graphql.ts +++ b/frontend/apollo/graphql.ts @@ -162,6 +162,14 @@ export type AppMemberInputType = { memberType?: InputMaybe; }; +export type AppMembershipType = { + __typename?: 'AppMembershipType'; + environments: Array>; + id: Scalars['String']['output']; + name: Scalars['String']['output']; + sseEnabled: Scalars['Boolean']['output']; +}; + export type AppType = { __typename?: 'AppType'; appSeed: Scalars['String']['output']; @@ -531,7 +539,7 @@ export type EnvironmentTokenType = { export type EnvironmentType = { __typename?: 'EnvironmentType'; - app: AppType; + app: AppMembershipType; createdAt?: Maybe; envType: ApiEnvironmentEnvTypeChoices; folderCount?: Maybe; @@ -549,6 +557,11 @@ export type EnvironmentType = { wrappedSeed?: Maybe; }; + +export type EnvironmentTypeSecretsArgs = { + path?: InputMaybe; +}; + export type GitHubRepoType = { __typename?: 'GitHubRepoType'; name?: Maybe; @@ -665,8 +678,8 @@ export enum MemberType { export type Mutation = { __typename?: 'Mutation'; addAppMember?: Maybe; - bulkInviteOrganisationMembers?: Maybe; bulkAddAppMembers?: Maybe; + bulkInviteOrganisationMembers?: Maybe; cancelSubscription?: Maybe; createApp?: Maybe; createAwsSecretSync?: Maybe; @@ -751,17 +764,17 @@ export type MutationAddAppMemberArgs = { }; +export type MutationBulkAddAppMembersArgs = { + appId: Scalars['ID']['input']; + members: Array>; +}; + export type MutationBulkInviteOrganisationMembersArgs = { invites: Array>; orgId: Scalars['ID']['input']; }; -export type MutationBulkAddAppMembersArgs = { - appId: Scalars['ID']['input']; - members: Array>; -}; - export type MutationCancelSubscriptionArgs = { organisationId?: InputMaybe; @@ -1303,7 +1316,7 @@ export type Node = { export type OrganisationMemberInviteType = { __typename?: 'OrganisationMemberInviteType'; - apps: Array; + apps: Array; createdAt?: Maybe; expiresAt: Scalars['DateTime']['output']; id: Scalars['String']['output']; @@ -1317,7 +1330,7 @@ export type OrganisationMemberInviteType = { export type OrganisationMemberType = { __typename?: 'OrganisationMemberType'; - appMemberships?: Maybe>; + appMemberships?: Maybe>; avatarUrl?: Maybe; createdAt?: Maybe; email?: Maybe; @@ -1601,9 +1614,9 @@ export type QueryOrganisationLicenseArgs = { export type QueryOrganisationMembersArgs = { + memberId?: InputMaybe; organisationId?: InputMaybe; role?: InputMaybe>>; - userId?: InputMaybe; }; @@ -1919,7 +1932,7 @@ export type ServiceAccountTokenType = { export type ServiceAccountType = { __typename?: 'ServiceAccountType'; - appMemberships?: Maybe>; + appMemberships?: Maybe>; createdAt?: Maybe; handlers?: Maybe>>; id: Scalars['String']['output']; @@ -2908,7 +2921,7 @@ export type GetOrganisationMembersQueryVariables = Exact<{ }>; -export type GetOrganisationMembersQuery = { __typename?: 'Query', organisationMembers?: Array<{ __typename?: 'OrganisationMemberType', id: string, identityKey?: string | null, email?: string | null, fullName?: string | null, avatarUrl?: string | null, createdAt?: any | null, lastLogin?: any | null, self?: boolean | null, role?: { __typename?: 'RoleType', id: string, name?: string | null, description?: string | null, permissions?: any | null, color?: string | null } | null, appMemberships?: Array<{ __typename?: 'AppType', id: string, name: string, sseEnabled: boolean, environments: Array<{ __typename?: 'EnvironmentType', id: string, name: string } | null> }> | null, tokens?: Array<{ __typename?: 'UserTokenType', id: string, name: string, createdAt?: any | null, expiresAt?: any | null }> | null, networkPolicies?: Array<{ __typename?: 'NetworkAccessPolicyType', id: string, name: string, allowedIps: string, isGlobal: boolean }> | null } | null> | null }; +export type GetOrganisationMembersQuery = { __typename?: 'Query', organisationMembers?: Array<{ __typename?: 'OrganisationMemberType', id: string, identityKey?: string | null, email?: string | null, fullName?: string | null, avatarUrl?: string | null, createdAt?: any | null, lastLogin?: any | null, self?: boolean | null, role?: { __typename?: 'RoleType', id: string, name?: string | null, description?: string | null, permissions?: any | null, color?: string | null } | null } | null> | null }; export type GetOrganisationPlanQueryVariables = Exact<{ organisationId: Scalars['ID']['input']; @@ -2929,7 +2942,7 @@ export type VerifyInviteQueryVariables = Exact<{ }>; -export type VerifyInviteQuery = { __typename?: 'Query', validateInvite?: { __typename?: 'OrganisationMemberInviteType', id: string, inviteeEmail: string, organisation: { __typename?: 'OrganisationType', id: string, name: string }, invitedBy: { __typename?: 'OrganisationMemberType', fullName?: string | null, email?: string | null }, apps: Array<{ __typename?: 'AppType', id: string, name: string }> } | null }; +export type VerifyInviteQuery = { __typename?: 'Query', validateInvite?: { __typename?: 'OrganisationMemberInviteType', id: string, inviteeEmail: string, organisation: { __typename?: 'OrganisationType', id: string, name: string }, invitedBy: { __typename?: 'OrganisationMemberType', fullName?: string | null, email?: string | null }, apps: Array<{ __typename?: 'AppMembershipType', id: string, name: string }> } | null }; export type GetAppEnvironmentsQueryVariables = Exact<{ appId: Scalars['ID']['input']; @@ -2938,16 +2951,17 @@ export type GetAppEnvironmentsQueryVariables = Exact<{ }>; -export type GetAppEnvironmentsQuery = { __typename?: 'Query', sseEnabled?: boolean | null, serverPublicKey?: string | null, appEnvironments?: Array<{ __typename?: 'EnvironmentType', id: string, name: string, envType: ApiEnvironmentEnvTypeChoices, identityKey: string, wrappedSeed?: string | null, wrappedSalt?: string | null, createdAt?: any | null, secretCount?: number | null, folderCount?: number | null, index: number, app: { __typename?: 'AppType', name: string, id: string }, members: Array<{ __typename?: 'OrganisationMemberType', email?: string | null, fullName?: string | null, avatarUrl?: string | null } | null> } | null> | null }; +export type GetAppEnvironmentsQuery = { __typename?: 'Query', sseEnabled?: boolean | null, serverPublicKey?: string | null, appEnvironments?: Array<{ __typename?: 'EnvironmentType', id: string, name: string, envType: ApiEnvironmentEnvTypeChoices, identityKey: string, wrappedSeed?: string | null, wrappedSalt?: string | null, createdAt?: any | null, secretCount?: number | null, folderCount?: number | null, index: number, app: { __typename?: 'AppMembershipType', name: string, id: string }, members: Array<{ __typename?: 'OrganisationMemberType', email?: string | null, fullName?: string | null, avatarUrl?: string | null } | null> } | null> | null }; export type GetAppSecretsQueryVariables = Exact<{ appId: Scalars['ID']['input']; memberId?: InputMaybe; memberType?: InputMaybe; + path?: InputMaybe; }>; -export type GetAppSecretsQuery = { __typename?: 'Query', sseEnabled?: boolean | null, serverPublicKey?: string | null, appEnvironments?: Array<{ __typename?: 'EnvironmentType', id: string, name: string, envType: ApiEnvironmentEnvTypeChoices, identityKey: string, wrappedSeed?: string | null, wrappedSalt?: string | null, createdAt?: any | null, secretCount?: number | null, folderCount?: number | null, index: number, app: { __typename?: 'AppType', name: string, id: string }, members: Array<{ __typename?: 'OrganisationMemberType', email?: string | null, fullName?: string | null, avatarUrl?: string | null } | null>, folders: Array<{ __typename?: 'SecretFolderType', id: string, name: string, path: string } | null>, secrets: Array<{ __typename?: 'SecretType', id: string, key: string, value: string, comment: string, path: string } | null> } | null> | null }; +export type GetAppSecretsQuery = { __typename?: 'Query', sseEnabled?: boolean | null, serverPublicKey?: string | null, appEnvironments?: Array<{ __typename?: 'EnvironmentType', id: string, name: string, envType: ApiEnvironmentEnvTypeChoices, identityKey: string, wrappedSeed?: string | null, wrappedSalt?: string | null, createdAt?: any | null, secretCount?: number | null, folderCount?: number | null, index: number, app: { __typename?: 'AppMembershipType', name: string, id: string }, members: Array<{ __typename?: 'OrganisationMemberType', email?: string | null, fullName?: string | null, avatarUrl?: string | null } | null>, folders: Array<{ __typename?: 'SecretFolderType', id: string, name: string, path: string } | null>, secrets: Array<{ __typename?: 'SecretType', id: string, key: string, value: string, comment: string, path: string } | null> } | null> | null }; export type GetAppSecretsLogsQueryVariables = Exact<{ appId: Scalars['ID']['input']; @@ -2985,6 +2999,13 @@ export type GetFoldersQueryVariables = Exact<{ export type GetFoldersQuery = { __typename?: 'Query', folders?: Array<{ __typename?: 'SecretFolderType', id: string, name: string, path: string, createdAt?: any | null, folderCount?: number | null, secretCount?: number | null } | null> | null }; +export type GetOrgSecretKeysQueryVariables = Exact<{ + organisationId: Scalars['ID']['input']; +}>; + + +export type GetOrgSecretKeysQuery = { __typename?: 'Query', apps?: Array<{ __typename?: 'AppType', id: string, name: string, environments: Array<{ __typename?: 'EnvironmentType', id: string, name: string, wrappedSeed?: string | null, wrappedSalt?: string | null, secrets: Array<{ __typename?: 'SecretType', id: string, key: string, path: string } | null> } | null> } | null> | null }; + export type GetSecretHistoryQueryVariables = Exact<{ appId: Scalars['ID']['input']; envId: Scalars['ID']['input']; @@ -3015,7 +3036,7 @@ export type GetSecretsQueryVariables = Exact<{ }>; -export type GetSecretsQuery = { __typename?: 'Query', secrets?: Array<{ __typename?: 'SecretType', id: string, key: string, value: string, path: string, comment: string, createdAt?: any | null, updatedAt: any, tags: Array<{ __typename?: 'SecretTagType', id: string, name: string, color: string }>, override?: { __typename?: 'PersonalSecretType', value?: string | null, isActive: boolean } | null, environment: { __typename?: 'EnvironmentType', id: string, app: { __typename?: 'AppType', id: string } } } | null> | null, folders?: Array<{ __typename?: 'SecretFolderType', id: string, name: string, path: string, createdAt?: any | null, folderCount?: number | null, secretCount?: number | null } | null> | null, appEnvironments?: Array<{ __typename?: 'EnvironmentType', id: string, name: string, envType: ApiEnvironmentEnvTypeChoices, identityKey: string, app: { __typename?: 'AppType', name: string } } | null> | null, environmentKeys?: Array<{ __typename?: 'EnvironmentKeyType', id: string, identityKey: string, wrappedSeed: string, wrappedSalt: string } | null> | null, envSyncs?: Array<{ __typename?: 'EnvironmentSyncType', id: string, options: any, isActive: boolean, status: ApiEnvironmentSyncStatusChoices, lastSync?: any | null, createdAt?: any | null, environment: { __typename?: 'EnvironmentType', id: string, name: string, envType: ApiEnvironmentEnvTypeChoices }, serviceInfo?: { __typename?: 'ServiceType', id?: string | null, name?: string | null } | null } | null> | null }; +export type GetSecretsQuery = { __typename?: 'Query', secrets?: Array<{ __typename?: 'SecretType', id: string, key: string, value: string, path: string, comment: string, createdAt?: any | null, updatedAt: any, tags: Array<{ __typename?: 'SecretTagType', id: string, name: string, color: string }>, override?: { __typename?: 'PersonalSecretType', value?: string | null, isActive: boolean } | null, environment: { __typename?: 'EnvironmentType', id: string, app: { __typename?: 'AppMembershipType', id: string } } } | null> | null, folders?: Array<{ __typename?: 'SecretFolderType', id: string, name: string, path: string, createdAt?: any | null, folderCount?: number | null, secretCount?: number | null } | null> | null, appEnvironments?: Array<{ __typename?: 'EnvironmentType', id: string, name: string, envType: ApiEnvironmentEnvTypeChoices, identityKey: string, app: { __typename?: 'AppMembershipType', name: string } } | null> | null, environmentKeys?: Array<{ __typename?: 'EnvironmentKeyType', id: string, identityKey: string, wrappedSeed: string, wrappedSalt: string } | null> | null, envSyncs?: Array<{ __typename?: 'EnvironmentSyncType', id: string, options: any, isActive: boolean, status: ApiEnvironmentSyncStatusChoices, lastSync?: any | null, createdAt?: any | null, environment: { __typename?: 'EnvironmentType', id: string, name: string, envType: ApiEnvironmentEnvTypeChoices }, serviceInfo?: { __typename?: 'ServiceType', id?: string | null, name?: string | null } | null } | null> | null }; export type GetServiceTokensQueryVariables = Exact<{ appId: Scalars['ID']['input']; @@ -3030,7 +3051,7 @@ export type GetServiceAccountDetailQueryVariables = Exact<{ }>; -export type GetServiceAccountDetailQuery = { __typename?: 'Query', serviceAccounts?: Array<{ __typename?: 'ServiceAccountType', id: string, name: string, identityKey?: string | null, createdAt?: any | null, role?: { __typename?: 'RoleType', id: string, name?: string | null, description?: string | null, color?: string | null, permissions?: any | null } | null, handlers?: Array<{ __typename?: 'ServiceAccountHandlerType', id: string, wrappedKeyring: string, wrappedRecovery: string, user: { __typename?: 'OrganisationMemberType', self?: boolean | null } } | null> | null, tokens?: Array<{ __typename?: 'ServiceAccountTokenType', id: string, name: string, createdAt?: any | null, expiresAt?: any | null, lastUsed?: any | null, createdBy?: { __typename?: 'OrganisationMemberType', fullName?: string | null, avatarUrl?: string | null, self?: boolean | null } | null } | null> | null, appMemberships?: Array<{ __typename?: 'AppType', id: string, name: string, sseEnabled: boolean, environments: Array<{ __typename?: 'EnvironmentType', id: string, name: string } | null> }> | null, networkPolicies?: Array<{ __typename?: 'NetworkAccessPolicyType', id: string, name: string, allowedIps: string, isGlobal: boolean }> | null } | null> | null }; +export type GetServiceAccountDetailQuery = { __typename?: 'Query', serviceAccounts?: Array<{ __typename?: 'ServiceAccountType', id: string, name: string, identityKey?: string | null, createdAt?: any | null, role?: { __typename?: 'RoleType', id: string, name?: string | null, description?: string | null, color?: string | null, permissions?: any | null } | null, handlers?: Array<{ __typename?: 'ServiceAccountHandlerType', id: string, wrappedKeyring: string, wrappedRecovery: string, user: { __typename?: 'OrganisationMemberType', self?: boolean | null } } | null> | null, tokens?: Array<{ __typename?: 'ServiceAccountTokenType', id: string, name: string, createdAt?: any | null, expiresAt?: any | null, lastUsed?: any | null, createdBy?: { __typename?: 'OrganisationMemberType', fullName?: string | null, avatarUrl?: string | null, self?: boolean | null } | null } | null> | null, appMemberships?: Array<{ __typename?: 'AppMembershipType', id: string, name: string, sseEnabled: boolean, environments: Array<{ __typename?: 'EnvironmentType', id: string, name: string } | null> }> | null, networkPolicies?: Array<{ __typename?: 'NetworkAccessPolicyType', id: string, name: string, allowedIps: string, isGlobal: boolean }> | null } | null> | null }; export type GetServiceAccountHandlersQueryVariables = Exact<{ orgId: Scalars['ID']['input']; @@ -3052,7 +3073,7 @@ export type GetOrganisationSyncsQueryVariables = Exact<{ }>; -export type GetOrganisationSyncsQuery = { __typename?: 'Query', syncs?: Array<{ __typename?: 'EnvironmentSyncType', id: string, path: string, options: any, isActive: boolean, lastSync?: any | null, status: ApiEnvironmentSyncStatusChoices, createdAt?: any | null, environment: { __typename?: 'EnvironmentType', id: string, name: string, envType: ApiEnvironmentEnvTypeChoices, app: { __typename?: 'AppType', id: string, name: string } }, serviceInfo?: { __typename?: 'ServiceType', id?: string | null, name?: string | null, provider?: { __typename?: 'ProviderType', id: string } | null } | null, authentication?: { __typename?: 'ProviderCredentialsType', id: string, name: string, credentials: any } | null, history: Array<{ __typename?: 'EnvironmentSyncEventType', id: string, status: ApiEnvironmentSyncEventStatusChoices, createdAt?: any | null, completedAt?: any | null, meta?: any | null }> } | null> | null, savedCredentials?: Array<{ __typename?: 'ProviderCredentialsType', id: string, name: string, credentials: any, createdAt?: any | null, syncCount?: number | null, provider?: { __typename?: 'ProviderType', id: string, name: string, expectedCredentials: Array, optionalCredentials: Array } | null } | null> | null, apps?: Array<{ __typename?: 'AppType', id: string, name: string, identityKey: string, createdAt?: any | null, sseEnabled: boolean, members: Array<{ __typename?: 'OrganisationMemberType', id: string, fullName?: string | null, avatarUrl?: string | null, email?: string | null } | null>, serviceAccounts: Array<{ __typename?: 'ServiceAccountType', id: string, name: string }>, environments: Array<{ __typename?: 'EnvironmentType', id: string, name: string, syncs: Array<{ __typename?: 'EnvironmentSyncType', id: string, status: ApiEnvironmentSyncStatusChoices, serviceInfo?: { __typename?: 'ServiceType', id?: string | null, name?: string | null, provider?: { __typename?: 'ProviderType', id: string, name: string } | null } | null } | null> } | null> } | null> | null }; +export type GetOrganisationSyncsQuery = { __typename?: 'Query', syncs?: Array<{ __typename?: 'EnvironmentSyncType', id: string, path: string, options: any, isActive: boolean, lastSync?: any | null, status: ApiEnvironmentSyncStatusChoices, createdAt?: any | null, environment: { __typename?: 'EnvironmentType', id: string, name: string, envType: ApiEnvironmentEnvTypeChoices, app: { __typename?: 'AppMembershipType', id: string, name: string } }, serviceInfo?: { __typename?: 'ServiceType', id?: string | null, name?: string | null, provider?: { __typename?: 'ProviderType', id: string } | null } | null, authentication?: { __typename?: 'ProviderCredentialsType', id: string, name: string, credentials: any } | null, history: Array<{ __typename?: 'EnvironmentSyncEventType', id: string, status: ApiEnvironmentSyncEventStatusChoices, createdAt?: any | null, completedAt?: any | null, meta?: any | null }> } | null> | null, savedCredentials?: Array<{ __typename?: 'ProviderCredentialsType', id: string, name: string, credentials: any, createdAt?: any | null, syncCount?: number | null, provider?: { __typename?: 'ProviderType', id: string, name: string, expectedCredentials: Array, optionalCredentials: Array } | null } | null> | null, apps?: Array<{ __typename?: 'AppType', id: string, name: string, identityKey: string, createdAt?: any | null, sseEnabled: boolean, members: Array<{ __typename?: 'OrganisationMemberType', id: string, fullName?: string | null, avatarUrl?: string | null, email?: string | null } | null>, serviceAccounts: Array<{ __typename?: 'ServiceAccountType', id: string, name: string }>, environments: Array<{ __typename?: 'EnvironmentType', id: string, name: string, syncs: Array<{ __typename?: 'EnvironmentSyncType', id: string, status: ApiEnvironmentSyncStatusChoices, serviceInfo?: { __typename?: 'ServiceType', id?: string | null, name?: string | null, provider?: { __typename?: 'ProviderType', id: string, name: string } | null } | null } | null> } | null> } | null> | null }; export type GetAwsSecretsQueryVariables = Exact<{ credentialId: Scalars['ID']['input']; @@ -3094,7 +3115,7 @@ export type GetAppSyncStatusQueryVariables = Exact<{ }>; -export type GetAppSyncStatusQuery = { __typename?: 'Query', sseEnabled?: boolean | null, serverPublicKey?: string | null, syncs?: Array<{ __typename?: 'EnvironmentSyncType', id: string, path: string, options: any, isActive: boolean, lastSync?: any | null, status: ApiEnvironmentSyncStatusChoices, createdAt?: any | null, environment: { __typename?: 'EnvironmentType', id: string, name: string, envType: ApiEnvironmentEnvTypeChoices, app: { __typename?: 'AppType', id: string, name: string } }, serviceInfo?: { __typename?: 'ServiceType', id?: string | null, name?: string | null, provider?: { __typename?: 'ProviderType', id: string } | null } | null, authentication?: { __typename?: 'ProviderCredentialsType', id: string, name: string, credentials: any } | null, history: Array<{ __typename?: 'EnvironmentSyncEventType', id: string, status: ApiEnvironmentSyncEventStatusChoices, createdAt?: any | null, completedAt?: any | null, meta?: any | null }> } | null> | null }; +export type GetAppSyncStatusQuery = { __typename?: 'Query', sseEnabled?: boolean | null, serverPublicKey?: string | null, syncs?: Array<{ __typename?: 'EnvironmentSyncType', id: string, path: string, options: any, isActive: boolean, lastSync?: any | null, status: ApiEnvironmentSyncStatusChoices, createdAt?: any | null, environment: { __typename?: 'EnvironmentType', id: string, name: string, envType: ApiEnvironmentEnvTypeChoices, app: { __typename?: 'AppMembershipType', id: string, name: string } }, serviceInfo?: { __typename?: 'ServiceType', id?: string | null, name?: string | null, provider?: { __typename?: 'ProviderType', id: string } | null } | null, authentication?: { __typename?: 'ProviderCredentialsType', id: string, name: string, credentials: any } | null, history: Array<{ __typename?: 'EnvironmentSyncEventType', id: string, status: ApiEnvironmentSyncEventStatusChoices, createdAt?: any | null, completedAt?: any | null, meta?: any | null }> } | null> | null }; export type GetProviderListQueryVariables = Exact<{ [key: string]: never; }>; @@ -3160,6 +3181,14 @@ export type GetVercelProjectsQueryVariables = Exact<{ export type GetVercelProjectsQuery = { __typename?: 'Query', vercelProjects?: Array<{ __typename?: 'VercelTeamProjectsType', id: string, teamName: string, projects?: Array<{ __typename?: 'VercelProjectType', id: string, name: string, environment?: Array | null } | null> | null } | null> | null }; +export type GetOrganisationMemberDetailQueryVariables = Exact<{ + organisationId: Scalars['ID']['input']; + id?: InputMaybe; +}>; + + +export type GetOrganisationMemberDetailQuery = { __typename?: 'Query', organisationMembers?: Array<{ __typename?: 'OrganisationMemberType', id: string, identityKey?: string | null, email?: string | null, fullName?: string | null, avatarUrl?: string | null, createdAt?: any | null, lastLogin?: any | null, self?: boolean | null, role?: { __typename?: 'RoleType', id: string, name?: string | null, description?: string | null, permissions?: any | null, color?: string | null } | null, appMemberships?: Array<{ __typename?: 'AppMembershipType', id: string, name: string, sseEnabled: boolean, environments: Array<{ __typename?: 'EnvironmentType', id: string, name: string } | null> }> | null, tokens?: Array<{ __typename?: 'UserTokenType', id: string, name: string, createdAt?: any | null, expiresAt?: any | null }> | null, networkPolicies?: Array<{ __typename?: 'NetworkAccessPolicyType', id: string, name: string, allowedIps: string, isGlobal: boolean }> | null } | null> | null }; + export type GetUserTokensQueryVariables = Exact<{ organisationId: Scalars['ID']['input']; }>; @@ -3260,16 +3289,17 @@ export const GetGlobalAccessUsersDocument = {"kind":"Document","definitions":[{" export const GetInvitesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetInvites"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orgId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"organisationInvites"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orgId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orgId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"self"}}]}},{"kind":"Field","name":{"kind":"Name","value":"inviteeEmail"}},{"kind":"Field","name":{"kind":"Name","value":"role"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"color"}}]}}]}}]}}]} as unknown as DocumentNode; export const GetLicenseDataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetLicenseData"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"license"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"customerName"}},{"kind":"Field","name":{"kind":"Name","value":"organisationName"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}},{"kind":"Field","name":{"kind":"Name","value":"plan"}},{"kind":"Field","name":{"kind":"Name","value":"seats"}},{"kind":"Field","name":{"kind":"Name","value":"isActivated"}},{"kind":"Field","name":{"kind":"Name","value":"organisationOwner"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]}}]} as unknown as DocumentNode; export const GetOrgLicenseDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOrgLicense"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"organisationLicense"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"organisationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"customerName"}},{"kind":"Field","name":{"kind":"Name","value":"issuedAt"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}},{"kind":"Field","name":{"kind":"Name","value":"activatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"plan"}},{"kind":"Field","name":{"kind":"Name","value":"seats"}},{"kind":"Field","name":{"kind":"Name","value":"tokens"}}]}}]}}]} as unknown as DocumentNode; -export const GetOrganisationMembersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOrganisationMembers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"role"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"organisationMembers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"organisationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}}},{"kind":"Argument","name":{"kind":"Name","value":"role"},"value":{"kind":"Variable","name":{"kind":"Name","value":"role"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"}},{"kind":"Field","name":{"kind":"Name","value":"color"}}]}},{"kind":"Field","name":{"kind":"Name","value":"identityKey"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"lastLogin"}},{"kind":"Field","name":{"kind":"Name","value":"self"}},{"kind":"Field","name":{"kind":"Name","value":"appMemberships"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sseEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"environments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"tokens"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"networkPolicies"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"allowedIps"}},{"kind":"Field","name":{"kind":"Name","value":"isGlobal"}}]}}]}}]}}]} as unknown as DocumentNode; +export const GetOrganisationMembersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOrganisationMembers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"role"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"organisationMembers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"organisationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}}},{"kind":"Argument","name":{"kind":"Name","value":"role"},"value":{"kind":"Variable","name":{"kind":"Name","value":"role"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"}},{"kind":"Field","name":{"kind":"Name","value":"color"}}]}},{"kind":"Field","name":{"kind":"Name","value":"identityKey"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"lastLogin"}},{"kind":"Field","name":{"kind":"Name","value":"self"}}]}}]}}]} as unknown as DocumentNode; export const GetOrganisationPlanDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOrganisationPlan"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"organisationPlan"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"organisationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"maxUsers"}},{"kind":"Field","name":{"kind":"Name","value":"maxApps"}},{"kind":"Field","name":{"kind":"Name","value":"maxEnvsPerApp"}},{"kind":"Field","name":{"kind":"Name","value":"seatsUsed"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"users"}},{"kind":"Field","name":{"kind":"Name","value":"serviceAccounts"}},{"kind":"Field","name":{"kind":"Name","value":"total"}}]}},{"kind":"Field","name":{"kind":"Name","value":"seatLimit"}},{"kind":"Field","name":{"kind":"Name","value":"appCount"}}]}}]}}]} as unknown as DocumentNode; export const GetRolesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetRoles"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orgId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"roles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orgId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orgId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"}},{"kind":"Field","name":{"kind":"Name","value":"isDefault"}}]}}]}}]} as unknown as DocumentNode; export const VerifyInviteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"VerifyInvite"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"inviteId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"validateInvite"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"inviteId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"inviteId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"organisation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"inviteeEmail"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}},{"kind":"Field","name":{"kind":"Name","value":"apps"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; export const GetAppEnvironmentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAppEnvironments"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"appId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"memberId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"memberType"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"MemberType"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"appEnvironments"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appId"}}},{"kind":"Argument","name":{"kind":"Name","value":"environmentId"},"value":{"kind":"NullValue"}},{"kind":"Argument","name":{"kind":"Name","value":"memberId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"memberId"}}},{"kind":"Argument","name":{"kind":"Name","value":"memberType"},"value":{"kind":"Variable","name":{"kind":"Name","value":"memberType"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"envType"}},{"kind":"Field","name":{"kind":"Name","value":"identityKey"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSeed"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSalt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"app"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"secretCount"}},{"kind":"Field","name":{"kind":"Name","value":"folderCount"}},{"kind":"Field","name":{"kind":"Name","value":"index"}},{"kind":"Field","name":{"kind":"Name","value":"members"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"sseEnabled"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appId"}}}]},{"kind":"Field","name":{"kind":"Name","value":"serverPublicKey"}}]}}]} as unknown as DocumentNode; -export const GetAppSecretsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAppSecrets"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"appId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"memberId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"memberType"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"MemberType"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"appEnvironments"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appId"}}},{"kind":"Argument","name":{"kind":"Name","value":"environmentId"},"value":{"kind":"NullValue"}},{"kind":"Argument","name":{"kind":"Name","value":"memberId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"memberId"}}},{"kind":"Argument","name":{"kind":"Name","value":"memberType"},"value":{"kind":"Variable","name":{"kind":"Name","value":"memberType"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"envType"}},{"kind":"Field","name":{"kind":"Name","value":"identityKey"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSeed"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSalt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"app"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"secretCount"}},{"kind":"Field","name":{"kind":"Name","value":"folderCount"}},{"kind":"Field","name":{"kind":"Name","value":"index"}},{"kind":"Field","name":{"kind":"Name","value":"members"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}}]}},{"kind":"Field","name":{"kind":"Name","value":"folders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"path"}}]}},{"kind":"Field","name":{"kind":"Name","value":"secrets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"comment"}},{"kind":"Field","name":{"kind":"Name","value":"path"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"sseEnabled"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appId"}}}]},{"kind":"Field","name":{"kind":"Name","value":"serverPublicKey"}}]}}]} as unknown as DocumentNode; +export const GetAppSecretsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAppSecrets"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"appId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"memberId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"memberType"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"MemberType"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"path"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"appEnvironments"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appId"}}},{"kind":"Argument","name":{"kind":"Name","value":"environmentId"},"value":{"kind":"NullValue"}},{"kind":"Argument","name":{"kind":"Name","value":"memberId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"memberId"}}},{"kind":"Argument","name":{"kind":"Name","value":"memberType"},"value":{"kind":"Variable","name":{"kind":"Name","value":"memberType"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"envType"}},{"kind":"Field","name":{"kind":"Name","value":"identityKey"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSeed"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSalt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"app"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"secretCount"}},{"kind":"Field","name":{"kind":"Name","value":"folderCount"}},{"kind":"Field","name":{"kind":"Name","value":"index"}},{"kind":"Field","name":{"kind":"Name","value":"members"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}}]}},{"kind":"Field","name":{"kind":"Name","value":"folders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"path"}}]}},{"kind":"Field","name":{"kind":"Name","value":"secrets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"path"},"value":{"kind":"Variable","name":{"kind":"Name","value":"path"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"comment"}},{"kind":"Field","name":{"kind":"Name","value":"path"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"sseEnabled"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appId"}}}]},{"kind":"Field","name":{"kind":"Name","value":"serverPublicKey"}}]}}]} as unknown as DocumentNode; export const GetAppSecretsLogsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAppSecretsLogs"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"appId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"start"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"BigInt"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"end"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"BigInt"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"eventTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"memberId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"memberType"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"MemberType"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"environmentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"secretLogs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appId"}}},{"kind":"Argument","name":{"kind":"Name","value":"start"},"value":{"kind":"Variable","name":{"kind":"Name","value":"start"}}},{"kind":"Argument","name":{"kind":"Name","value":"end"},"value":{"kind":"Variable","name":{"kind":"Name","value":"end"}}},{"kind":"Argument","name":{"kind":"Name","value":"eventTypes"},"value":{"kind":"Variable","name":{"kind":"Name","value":"eventTypes"}}},{"kind":"Argument","name":{"kind":"Name","value":"memberId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"memberId"}}},{"kind":"Argument","name":{"kind":"Name","value":"memberType"},"value":{"kind":"Variable","name":{"kind":"Name","value":"memberType"}}},{"kind":"Argument","name":{"kind":"Name","value":"environmentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"environmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"logs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"color"}}]}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"comment"}},{"kind":"Field","name":{"kind":"Name","value":"timestamp"}},{"kind":"Field","name":{"kind":"Name","value":"ipAddress"}},{"kind":"Field","name":{"kind":"Name","value":"userAgent"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}}]}},{"kind":"Field","name":{"kind":"Name","value":"serviceToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"serviceAccount"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"serviceAccountToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"eventType"}},{"kind":"Field","name":{"kind":"Name","value":"environment"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"envType"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"secret"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}},{"kind":"Field","name":{"kind":"Name","value":"environmentKeys"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"identityKey"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSeed"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSalt"}},{"kind":"Field","name":{"kind":"Name","value":"environment"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; export const GetEnvironmentKeyDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetEnvironmentKey"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"envId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"appId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"environmentKeys"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"environmentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}},{"kind":"Argument","name":{"kind":"Name","value":"appId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"identityKey"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSeed"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSalt"}}]}}]}}]} as unknown as DocumentNode; export const GetEnvironmentTokensDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetEnvironmentTokens"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"envId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"environmentTokens"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"environmentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedKeyShare"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]} as unknown as DocumentNode; export const GetFoldersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetFolders"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"envId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"path"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"folders"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"envId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}},{"kind":"Argument","name":{"kind":"Name","value":"path"},"value":{"kind":"Variable","name":{"kind":"Name","value":"path"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"folderCount"}},{"kind":"Field","name":{"kind":"Name","value":"secretCount"}}]}}]}}]} as unknown as DocumentNode; +export const GetOrgSecretKeysDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOrgSecretKeys"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"apps"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"organisationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"environments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSeed"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSalt"}},{"kind":"Field","name":{"kind":"Name","value":"secrets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"path"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const GetSecretHistoryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSecretHistory"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"appId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"envId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"secrets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"envId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}},{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"history"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"color"}}]}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"comment"}},{"kind":"Field","name":{"kind":"Name","value":"timestamp"}},{"kind":"Field","name":{"kind":"Name","value":"ipAddress"}},{"kind":"Field","name":{"kind":"Name","value":"userAgent"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}}]}},{"kind":"Field","name":{"kind":"Name","value":"serviceToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"serviceAccount"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"eventType"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"environmentKeys"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appId"}}},{"kind":"Argument","name":{"kind":"Name","value":"environmentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"identityKey"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSeed"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSalt"}}]}}]}}]} as unknown as DocumentNode; export const GetEnvSecretsKvDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetEnvSecretsKV"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"envId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"folders"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"envId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}},{"kind":"Argument","name":{"kind":"Name","value":"path"},"value":{"kind":"StringValue","value":"/","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"secrets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"envId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}},{"kind":"Argument","name":{"kind":"Name","value":"path"},"value":{"kind":"StringValue","value":"/","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"comment"}},{"kind":"Field","name":{"kind":"Name","value":"path"}}]}},{"kind":"Field","name":{"kind":"Name","value":"environmentKeys"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"environmentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"identityKey"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSeed"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedSalt"}}]}}]}}]} as unknown as DocumentNode; export const GetSecretTagsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSecretTags"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orgId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"secretTags"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orgId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orgId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"color"}}]}}]}}]} as unknown as DocumentNode; @@ -3295,4 +3325,5 @@ export const TestNomadAuthDocument = {"kind":"Document","definitions":[{"kind":" export const GetRailwayProjectsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetRailwayProjects"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"railwayProjects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"environments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; export const TestVaultAuthDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"TestVaultAuth"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"testVaultCreds"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}}]}]}}]} as unknown as DocumentNode; export const GetVercelProjectsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetVercelProjects"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"vercelProjects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"teamName"}},{"kind":"Field","name":{"kind":"Name","value":"projects"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"environment"}}]}}]}}]}}]} as unknown as DocumentNode; +export const GetOrganisationMemberDetailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOrganisationMemberDetail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"organisationMembers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"organisationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}}},{"kind":"Argument","name":{"kind":"Name","value":"memberId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"}},{"kind":"Field","name":{"kind":"Name","value":"color"}}]}},{"kind":"Field","name":{"kind":"Name","value":"identityKey"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"lastLogin"}},{"kind":"Field","name":{"kind":"Name","value":"self"}},{"kind":"Field","name":{"kind":"Name","value":"appMemberships"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sseEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"environments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"tokens"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"networkPolicies"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"allowedIps"}},{"kind":"Field","name":{"kind":"Name","value":"isGlobal"}}]}}]}}]}}]} as unknown as DocumentNode; export const GetUserTokensDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetUserTokens"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userTokens"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"organisationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"organisationId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"wrappedKeyShare"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/frontend/apollo/schema.graphql b/frontend/apollo/schema.graphql index 91607f88e..2d96eeebf 100644 --- a/frontend/apollo/schema.graphql +++ b/frontend/apollo/schema.graphql @@ -7,15 +7,28 @@ type Query { license: PhaseLicenseType organisationLicense(organisationId: ID): ActivatedPhaseLicenseType organisationPlan(organisationId: ID): OrganisationPlanType - organisationMembers(organisationId: ID, userId: ID, role: [String]): [OrganisationMemberType] + organisationMembers(organisationId: ID, memberId: ID, role: [String]): [OrganisationMemberType] organisationGlobalAccessUsers(organisationId: ID): [OrganisationMemberType] organisationInvites(orgId: ID): [OrganisationMemberInviteType] validateInvite(inviteId: ID): OrganisationMemberInviteType apps(organisationId: ID, appId: ID): [AppType] kmsLogs(appId: ID, start: BigInt, end: BigInt): KMSLogsResponseType - secretLogs(appId: ID, start: BigInt, end: BigInt, eventTypes: [String], memberId: ID, memberType: MemberType, environmentId: ID): SecretLogsResponseType + secretLogs( + appId: ID + start: BigInt + end: BigInt + eventTypes: [String] + memberId: ID + memberType: MemberType + environmentId: ID + ): SecretLogsResponseType appActivityChart(appId: ID, period: TimeRange): [ChartDataPointType] - appEnvironments(appId: ID, environmentId: ID, memberId: ID, memberType: MemberType): [EnvironmentType] + appEnvironments( + appId: ID + environmentId: ID + memberId: ID + memberType: MemberType + ): [EnvironmentType] appUsers(appId: ID): [OrganisationMemberType] appServiceAccounts(appId: ID): [ServiceAccountType] secrets(envId: ID, path: String, id: ID): [SecretType] @@ -47,7 +60,11 @@ type Query { testVaultCreds(credentialId: ID): Boolean testNomadCreds(credentialId: ID): Boolean validateAwsAssumeRoleAuth: AWSValidationResultType - validateAwsAssumeRoleCredentials(roleArn: String!, region: String, externalId: String): AWSValidationResultType + validateAwsAssumeRoleCredentials( + roleArn: String! + region: String + externalId: String + ): AWSValidationResultType stripeCheckoutDetails(stripeSessionId: String!): StripeCheckoutDetails stripeSubscriptionDetails(organisationId: ID): StripeSubscriptionDetails } @@ -73,13 +90,19 @@ value as specified by scalar DateTime enum ApiOrganisationPlanChoices { - """Free""" + """ + Free + """ FR - """Pro""" + """ + Pro + """ PR - """Enterprise""" + """ + Enterprise + """ EN } @@ -148,65 +171,90 @@ type OrganisationMemberType { avatarUrl: String self: Boolean lastLogin: DateTime - appMemberships: [AppType!] + appMemberships: [AppMembershipType!] tokens: [UserTokenType!] networkPolicies: [NetworkAccessPolicyType!] } -type AppType { +type AppMembershipType { + id: String! + name: String! + sseEnabled: Boolean! + environments: [EnvironmentType]! +} + +type EnvironmentType { id: String! + app: AppMembershipType! name: String! + envType: ApiEnvironmentEnvTypeChoices! + index: Int! identityKey: String! - appVersion: Int! - appToken: String! - appSeed: String! - wrappedKeyShare: String! + wrappedSeed: String + wrappedSalt: String createdAt: DateTime updatedAt: DateTime! - sseEnabled: Boolean! - serviceAccounts: [ServiceAccountType!]! - environments: [EnvironmentType]! + folders: [SecretFolderType]! + secrets(path: String): [SecretType]! + folderCount: Int + secretCount: Int members: [OrganisationMemberType]! + syncs: [EnvironmentSyncType]! } -type ServiceAccountType { +enum ApiEnvironmentEnvTypeChoices { + """ + Development + """ + DEV + + """ + Staging + """ + STAGING + + """ + Production + """ + PROD + + """ + Custom + """ + CUSTOM +} + +type SecretFolderType { id: String! + environment: EnvironmentType! + path: String! name: String! - role: RoleType - identityKey: String createdAt: DateTime updatedAt: DateTime! - thirdPartyAuthEnabled: Boolean - handlers: [ServiceAccountHandlerType] - tokens: [ServiceAccountTokenType] - appMemberships: [AppType!] - networkPolicies: [NetworkAccessPolicyType!] + folderCount: Int + secretCount: Int } -type ServiceAccountHandlerType { +type SecretType { id: String! - serviceAccount: ServiceAccountType! - user: OrganisationMemberType! - wrappedKeyring: String! - wrappedRecovery: String! + environment: EnvironmentType! + folder: SecretFolderType + path: String! + key: String! + value: String! + version: Int! + tags: [SecretTagType!]! + comment: String! createdAt: DateTime updatedAt: DateTime! + history: [SecretEventType] + override: PersonalSecretType } -type ServiceAccountTokenType { +type SecretTagType { id: String! - serviceAccount: ServiceAccountType! name: String! - identityKey: String! - token: String! - wrappedKeyShare: String! - createdBy: OrganisationMemberType - createdAt: DateTime - updatedAt: DateTime! - deletedAt: DateTime - expiresAt: DateTime - secreteventSet: [SecretEventType!]! - lastUsed: DateTime + color: String! } type SecretEventType { @@ -229,64 +277,99 @@ type SecretEventType { userAgent: String } -type SecretType { +type ServiceTokenType { + id: String! + keys: [ServerEnvironmentKeyType!]! + identityKey: String! + token: String! + wrappedKeyShare: String! + name: String! + createdBy: OrganisationMemberType + createdAt: DateTime + updatedAt: DateTime! + expiresAt: DateTime +} + +type ServerEnvironmentKeyType { id: String! environment: EnvironmentType! - folder: SecretFolderType - path: String! - key: String! - value: String! - version: Int! - tags: [SecretTagType!]! - comment: String! + identityKey: String! + wrappedSeed: String! + wrappedSalt: String! createdAt: DateTime updatedAt: DateTime! - history: [SecretEventType] - override: PersonalSecretType } -type EnvironmentType { +type ServiceAccountType { id: String! - app: AppType! name: String! - envType: ApiEnvironmentEnvTypeChoices! - index: Int! + role: RoleType + identityKey: String + createdAt: DateTime + updatedAt: DateTime! + thirdPartyAuthEnabled: Boolean + handlers: [ServiceAccountHandlerType] + tokens: [ServiceAccountTokenType] + appMemberships: [AppMembershipType!] + networkPolicies: [NetworkAccessPolicyType!] +} + +type ServiceAccountHandlerType { + id: String! + serviceAccount: ServiceAccountType! + user: OrganisationMemberType! + wrappedKeyring: String! + wrappedRecovery: String! + createdAt: DateTime + updatedAt: DateTime! +} + +type ServiceAccountTokenType { + id: String! + serviceAccount: ServiceAccountType! + name: String! identityKey: String! - wrappedSeed: String - wrappedSalt: String + token: String! + wrappedKeyShare: String! + createdBy: OrganisationMemberType createdAt: DateTime updatedAt: DateTime! - folders: [SecretFolderType]! - secrets: [SecretType]! - folderCount: Int - secretCount: Int - members: [OrganisationMemberType]! - syncs: [EnvironmentSyncType]! + deletedAt: DateTime + expiresAt: DateTime + secreteventSet: [SecretEventType!]! + lastUsed: DateTime } -enum ApiEnvironmentEnvTypeChoices { - """Development""" - DEV +enum ApiSecretEventEventTypeChoices { + """ + Create + """ + C - """Staging""" - STAGING + """ + Read + """ + R - """Production""" - PROD + """ + Update + """ + U - """Custom""" - CUSTOM + """ + Delete + """ + D } -type SecretFolderType { +type PersonalSecretType { id: String! - environment: EnvironmentType! - path: String! - name: String! + secret: SecretType! + user: OrganisationMemberType! + value: String + isActive: Boolean! createdAt: DateTime updatedAt: DateTime! - folderCount: Int - secretCount: Int } type EnvironmentSyncType { @@ -322,19 +405,29 @@ type ProviderType { } enum ApiEnvironmentSyncStatusChoices { - """In progress""" + """ + In progress + """ IN_PROGRESS - """Completed""" + """ + Completed + """ COMPLETED - """cancelled""" + """ + cancelled + """ CANCELLED - """Timed out""" + """ + Timed out + """ TIMED_OUT - """Failed""" + """ + Failed + """ FAILED } @@ -355,75 +448,32 @@ type EnvironmentSyncEventType { } enum ApiEnvironmentSyncEventStatusChoices { - """In progress""" + """ + In progress + """ IN_PROGRESS - """Completed""" + """ + Completed + """ COMPLETED - """cancelled""" + """ + cancelled + """ CANCELLED - """Timed out""" + """ + Timed out + """ TIMED_OUT - """Failed""" + """ + Failed + """ FAILED } -type SecretTagType { - id: String! - name: String! - color: String! -} - -type PersonalSecretType { - id: String! - secret: SecretType! - user: OrganisationMemberType! - value: String - isActive: Boolean! - createdAt: DateTime - updatedAt: DateTime! -} - -type ServiceTokenType { - id: String! - keys: [ServerEnvironmentKeyType!]! - identityKey: String! - token: String! - wrappedKeyShare: String! - name: String! - createdBy: OrganisationMemberType - createdAt: DateTime - updatedAt: DateTime! - expiresAt: DateTime -} - -type ServerEnvironmentKeyType { - id: String! - environment: EnvironmentType! - identityKey: String! - wrappedSeed: String! - wrappedSalt: String! - createdAt: DateTime - updatedAt: DateTime! -} - -enum ApiSecretEventEventTypeChoices { - """Create""" - C - - """Read""" - R - - """Update""" - U - - """Delete""" - D -} - type UserTokenType { id: String! name: String! @@ -483,20 +533,26 @@ type ActivatedPhaseLicenseType { } enum ApiActivatedPhaseLicensePlanChoices { - """Free""" + """ + Free + """ FR - """Pro""" + """ + Pro + """ PR - """Enterprise""" + """ + Enterprise + """ EN } type OrganisationMemberInviteType { id: String! organisation: OrganisationType! - apps: [AppType!]! + apps: [AppMembershipType!]! role: RoleType invitedBy: OrganisationMemberType! inviteeEmail: String! @@ -506,6 +562,22 @@ type OrganisationMemberInviteType { expiresAt: DateTime! } +type AppType { + id: String! + name: String! + identityKey: String! + appVersion: Int! + appToken: String! + appSeed: String! + wrappedKeyShare: String! + createdAt: DateTime + updatedAt: DateTime! + sseEnabled: Boolean! + serviceAccounts: [ServiceAccountType!]! + environments: [EnvironmentType]! + members: [OrganisationMemberType]! +} + type KMSLogsResponseType { logs: [KMSLogType] count: Int @@ -528,9 +600,13 @@ type KMSLogType implements Node { longitude: Float } -"""An object with an ID""" +""" +An object with an ID +""" interface Node { - """The ID of the object""" + """ + The ID of the object + """ id: ID! } @@ -745,61 +821,244 @@ enum PlanTypeEnum { } type Mutation { - createOrganisation(id: ID!, identityKey: String!, name: String!, wrappedKeyring: String!, wrappedRecovery: String!): CreateOrganisationMutation - bulkInviteOrganisationMembers(invites: [InviteInput]!, orgId: ID!): BulkInviteOrganisationMembersMutation - createOrganisationMember(identityKey: String!, inviteId: ID!, orgId: ID!, wrappedKeyring: String, wrappedRecovery: String): CreateOrganisationMemberMutation + createOrganisation( + id: ID! + identityKey: String! + name: String! + wrappedKeyring: String! + wrappedRecovery: String! + ): CreateOrganisationMutation + bulkInviteOrganisationMembers( + invites: [InviteInput]! + orgId: ID! + ): BulkInviteOrganisationMembersMutation + createOrganisationMember( + identityKey: String! + inviteId: ID! + orgId: ID! + wrappedKeyring: String + wrappedRecovery: String + ): CreateOrganisationMemberMutation deleteOrganisationMember(memberId: ID!): DeleteOrganisationMemberMutation updateOrganisationMemberRole(memberId: ID!, roleId: ID!): UpdateOrganisationMemberRole - updateMemberWrappedSecrets(orgId: ID!, wrappedKeyring: String!, wrappedRecovery: String!): UpdateUserWrappedSecretsMutation + updateMemberWrappedSecrets( + orgId: ID! + wrappedKeyring: String! + wrappedRecovery: String! + ): UpdateUserWrappedSecretsMutation deleteInvitation(inviteId: ID!): DeleteInviteMutation - createApp(appSeed: String!, appToken: String!, appVersion: Int!, id: ID!, identityKey: String!, name: String!, organisationId: ID!, wrappedKeyShare: String!): CreateAppMutation + createApp( + appSeed: String! + appToken: String! + appVersion: Int! + id: ID! + identityKey: String! + name: String! + organisationId: ID! + wrappedKeyShare: String! + ): CreateAppMutation rotateAppKeys(appToken: String!, id: ID!, wrappedKeyShare: String!): RotateAppKeysMutation deleteApp(id: ID!): DeleteAppMutation updateAppName(id: ID!, name: String!): UpdateAppNameMutation - addAppMember(appId: ID, envKeys: [EnvironmentKeyInput], memberId: ID, memberType: MemberType): AddAppMemberMutation + addAppMember( + appId: ID + envKeys: [EnvironmentKeyInput] + memberId: ID + memberType: MemberType + ): AddAppMemberMutation bulkAddAppMembers(appId: ID!, members: [AppMemberInputType]!): BulkAddAppMembersMutation removeAppMember(appId: ID, memberId: ID, memberType: MemberType): RemoveAppMemberMutation - updateMemberEnvironmentScope(appId: ID, envKeys: [EnvironmentKeyInput], memberId: ID, memberType: MemberType): UpdateMemberEnvScopeMutation - createEnvironment(adminKeys: [EnvironmentKeyInput], environmentData: EnvironmentInput!, wrappedSalt: String, wrappedSeed: String): CreateEnvironmentMutation + updateMemberEnvironmentScope( + appId: ID + envKeys: [EnvironmentKeyInput] + memberId: ID + memberType: MemberType + ): UpdateMemberEnvScopeMutation + createEnvironment( + adminKeys: [EnvironmentKeyInput] + environmentData: EnvironmentInput! + wrappedSalt: String + wrappedSeed: String + ): CreateEnvironmentMutation deleteEnvironment(environmentId: ID!): DeleteEnvironmentMutation renameEnvironment(environmentId: ID!, name: String!): RenameEnvironmentMutation swapEnvironmentOrder(environment1Id: ID!, environment2Id: ID!): SwapEnvironmentOrderMutation - createEnvironmentKey(envId: ID!, identityKey: String!, userId: ID, wrappedSalt: String!, wrappedSeed: String!): CreateEnvironmentKeyMutation - createEnvironmentToken(envId: ID!, identityKey: String!, name: String!, token: String!, wrappedKeyShare: String!): CreateEnvironmentTokenMutation - createCustomRole(color: String, description: String, name: String, organisationId: ID!, permissions: JSONString): CreateCustomRoleMutation - updateCustomRole(color: String, description: String, id: ID!, name: String, permissions: JSONString): UpdateCustomRoleMutation + createEnvironmentKey( + envId: ID! + identityKey: String! + userId: ID + wrappedSalt: String! + wrappedSeed: String! + ): CreateEnvironmentKeyMutation + createEnvironmentToken( + envId: ID! + identityKey: String! + name: String! + token: String! + wrappedKeyShare: String! + ): CreateEnvironmentTokenMutation + createCustomRole( + color: String + description: String + name: String + organisationId: ID! + permissions: JSONString + ): CreateCustomRoleMutation + updateCustomRole( + color: String + description: String + id: ID! + name: String + permissions: JSONString + ): UpdateCustomRoleMutation deleteCustomRole(id: ID!): DeleteCustomRoleMutation - createNetworkAccessPolicy(allowedIps: String!, isGlobal: Boolean!, name: String, organisationId: ID!): CreateNetworkAccessPolicyMutation + createNetworkAccessPolicy( + allowedIps: String! + isGlobal: Boolean! + name: String + organisationId: ID! + ): CreateNetworkAccessPolicyMutation updateNetworkAccessPolicy(policyInputs: [UpdatePolicyInput]): UpdateNetworkAccessPolicyMutation deleteNetworkAccessPolicy(id: ID!): DeleteNetworkAccessPolicyMutation - updateAccountNetworkAccessPolicies(accountInputs: [AccountPolicyInput], organisationId: ID!): UpdateAccountNetworkAccessPolicies - createServiceAccount(handlers: [ServiceAccountHandlerInput], identityKey: String, name: String, organisationId: ID, roleId: ID, serverWrappedKeyring: String, serverWrappedRecovery: String): CreateServiceAccountMutation - enableServiceAccountThirdPartyAuth(serverWrappedKeyring: String, serverWrappedRecovery: String, serviceAccountId: ID): EnableServiceAccountThirdPartyAuthMutation - updateServiceAccountHandlers(handlers: [ServiceAccountHandlerInput], organisationId: ID): UpdateServiceAccountHandlersMutation + updateAccountNetworkAccessPolicies( + accountInputs: [AccountPolicyInput] + organisationId: ID! + ): UpdateAccountNetworkAccessPolicies + createServiceAccount( + handlers: [ServiceAccountHandlerInput] + identityKey: String + name: String + organisationId: ID + roleId: ID + serverWrappedKeyring: String + serverWrappedRecovery: String + ): CreateServiceAccountMutation + enableServiceAccountThirdPartyAuth( + serverWrappedKeyring: String + serverWrappedRecovery: String + serviceAccountId: ID + ): EnableServiceAccountThirdPartyAuthMutation + updateServiceAccountHandlers( + handlers: [ServiceAccountHandlerInput] + organisationId: ID + ): UpdateServiceAccountHandlersMutation updateServiceAccount(name: String, roleId: ID, serviceAccountId: ID): UpdateServiceAccountMutation deleteServiceAccount(serviceAccountId: ID): DeleteServiceAccountMutation - createServiceAccountToken(expiry: BigInt, identityKey: String!, name: String!, serviceAccountId: ID, token: String!, wrappedKeyShare: String!): CreateServiceAccountTokenMutation + createServiceAccountToken( + expiry: BigInt + identityKey: String! + name: String! + serviceAccountId: ID + token: String! + wrappedKeyShare: String! + ): CreateServiceAccountTokenMutation deleteServiceAccountToken(tokenId: ID): DeleteServiceAccountTokenMutation initEnvSync(appId: ID, envKeys: [EnvironmentKeyInput]): InitEnvSync deleteEnvSync(syncId: ID): DeleteSync triggerSync(syncId: ID): TriggerSync toggleSyncActive(syncId: ID): ToggleSyncActive updateSyncAuthentication(credentialId: ID, syncId: ID): UpdateSyncAuthentication - createProviderCredentials(credentials: JSONString, name: String, orgId: ID, provider: String): CreateProviderCredentials - updateProviderCredentials(credentialId: ID, credentials: JSONString, name: String): UpdateProviderCredentials + createProviderCredentials( + credentials: JSONString + name: String + orgId: ID + provider: String + ): CreateProviderCredentials + updateProviderCredentials( + credentialId: ID + credentials: JSONString + name: String + ): UpdateProviderCredentials deleteProviderCredentials(credentialId: ID): DeleteProviderCredentials - createCloudflarePagesSync(credentialId: ID, deploymentId: ID, envId: ID, path: String, projectEnv: String, projectName: String): CreateCloudflarePagesSync - createCloudflareWorkersSync(credentialId: ID, envId: ID, path: String, workerName: String): CreateCloudflareWorkersSync - createAwsSecretSync(credentialId: ID, envId: ID, kmsId: String, path: String, secretName: String): CreateAWSSecretsManagerSync - createGhActionsSync(credentialId: ID, envId: ID, owner: String, path: String, repoName: String): CreateGitHubActionsSync - createVaultSync(credentialId: ID, engine: String, envId: ID, path: String, vaultPath: String): CreateVaultSync - createNomadSync(credentialId: ID, envId: ID, nomadNamespace: String, nomadPath: String, path: String): CreateNomadSync - createGitlabCiSync(credentialId: ID, envId: ID, isGroup: Boolean, masked: Boolean, path: String, protected: Boolean, resourceId: String, resourcePath: String): CreateGitLabCISync - createRailwaySync(credentialId: ID, envId: ID, path: String, railwayEnvironment: RailwayResourceInput, railwayProject: RailwayResourceInput, railwayService: RailwayResourceInput): CreateRailwaySync - createVercelSync(credentialId: ID, envId: ID, environment: String, path: String, projectId: String, projectName: String, secretType: String, teamId: String, teamName: String): CreateVercelSync - createUserToken(expiry: BigInt, identityKey: String!, name: String!, orgId: ID!, token: String!, wrappedKeyShare: String!): CreateUserTokenMutation + createCloudflarePagesSync( + credentialId: ID + deploymentId: ID + envId: ID + path: String + projectEnv: String + projectName: String + ): CreateCloudflarePagesSync + createCloudflareWorkersSync( + credentialId: ID + envId: ID + path: String + workerName: String + ): CreateCloudflareWorkersSync + createAwsSecretSync( + credentialId: ID + envId: ID + kmsId: String + path: String + secretName: String + ): CreateAWSSecretsManagerSync + createGhActionsSync( + credentialId: ID + envId: ID + owner: String + path: String + repoName: String + ): CreateGitHubActionsSync + createVaultSync( + credentialId: ID + engine: String + envId: ID + path: String + vaultPath: String + ): CreateVaultSync + createNomadSync( + credentialId: ID + envId: ID + nomadNamespace: String + nomadPath: String + path: String + ): CreateNomadSync + createGitlabCiSync( + credentialId: ID + envId: ID + isGroup: Boolean + masked: Boolean + path: String + protected: Boolean + resourceId: String + resourcePath: String + ): CreateGitLabCISync + createRailwaySync( + credentialId: ID + envId: ID + path: String + railwayEnvironment: RailwayResourceInput + railwayProject: RailwayResourceInput + railwayService: RailwayResourceInput + ): CreateRailwaySync + createVercelSync( + credentialId: ID + envId: ID + environment: String + path: String + projectId: String + projectName: String + secretType: String + teamId: String + teamName: String + ): CreateVercelSync + createUserToken( + expiry: BigInt + identityKey: String! + name: String! + orgId: ID! + token: String! + wrappedKeyShare: String! + ): CreateUserTokenMutation deleteUserToken(tokenId: ID!): DeleteUserTokenMutation - createServiceToken(appId: ID!, environmentKeys: [EnvironmentKeyInput], expiry: BigInt, identityKey: String!, name: String!, token: String!, wrappedKeyShare: String!): CreateServiceTokenMutation + createServiceToken( + appId: ID! + environmentKeys: [EnvironmentKeyInput] + expiry: BigInt + identityKey: String! + name: String! + token: String! + wrappedKeyShare: String! + ): CreateServiceTokenMutation deleteServiceToken(tokenId: ID!): DeleteServiceTokenMutation createSecretFolder(envId: ID, name: String, path: String): CreateSecretFolderMutation deleteSecretFolder(folderId: ID): DeleteSecretFolderMutation @@ -814,16 +1073,27 @@ type Mutation { createOverride(overrideData: PersonalSecretInput): CreatePersonalSecretMutation removeOverride(secretId: ID): DeletePersonalSecretMutation createLockbox(input: LockboxInput): CreateLockboxMutation - createSubscriptionCheckoutSession(billingPeriod: BillingPeriodEnum, organisationId: ID!, planType: PlanTypeEnum): CreateSubscriptionCheckoutSession + createSubscriptionCheckoutSession( + billingPeriod: BillingPeriodEnum + organisationId: ID! + planType: PlanTypeEnum + ): CreateSubscriptionCheckoutSession deletePaymentMethod(organisationId: ID, paymentMethodId: String): DeletePaymentMethodMutation cancelSubscription(organisationId: ID, subscriptionId: String!): UpdateSubscriptionResponse resumeSubscription(organisationId: ID, subscriptionId: String!): UpdateSubscriptionResponse - modifySubscription(billingPeriod: BillingPeriodEnum, organisationId: ID!, planType: PlanTypeEnum, subscriptionId: String!): UpdateSubscriptionResponse + modifySubscription( + billingPeriod: BillingPeriodEnum + organisationId: ID! + planType: PlanTypeEnum + subscriptionId: String! + ): UpdateSubscriptionResponse createSetupIntent(organisationId: ID): CreateSetupIntentMutation setDefaultPaymentMethod( organisationId: ID - """Payment Method ID to set as default""" + """ + Payment Method ID to set as default + """ paymentMethodId: String! ): SetDefaultPaymentMethodMutation } @@ -1217,4 +1487,4 @@ type CreateSetupIntentMutation { type SetDefaultPaymentMethodMutation { ok: Boolean -} \ No newline at end of file +} diff --git a/frontend/app/[team]/access/members/[memberId]/page.tsx b/frontend/app/[team]/access/members/[memberId]/page.tsx index 38abe9448..02816f32c 100644 --- a/frontend/app/[team]/access/members/[memberId]/page.tsx +++ b/frontend/app/[team]/access/members/[memberId]/page.tsx @@ -2,7 +2,7 @@ import Spinner from '@/components/common/Spinner' import { organisationContext } from '@/contexts/organisationContext' -import GetOrganisationMembers from '@/graphql/queries/organisation/getOrganisationMembers.gql' +import { GetOrganisationMemberDetail } from '@/graphql/queries/users/getOrganisationMemberDetail.gql' import { userHasPermission } from '@/utils/access/permissions' import { useQuery } from '@apollo/client' import Link from 'next/link' @@ -10,7 +10,7 @@ import { useContext } from 'react' import { FaBan, FaChevronLeft, FaClock, FaCog, FaKey, FaNetworkWired } from 'react-icons/fa' import { Avatar } from '@/components/common/Avatar' import { EmptyState } from '@/components/common/EmptyState' -import { OrganisationMemberType, UserTokenType, AppType } from '@/apollo/graphql' +import { OrganisationMemberType, UserTokenType, AppMembershipType } from '@/apollo/graphql' import { DeleteMemberConfirmDialog } from '../_components/DeleteMemberConfirmDialog' import { RoleSelector } from '../_components/RoleSelector' import { relativeTimeFromDates } from '@/utils/time' @@ -59,19 +59,16 @@ export default function MemberDetail({ params }: { params: { team: string; membe ? userHasPermission(organisation.role!.permissions, 'MemberPersonalAccessTokens', 'delete') : false - const { data, loading, error } = useQuery(GetOrganisationMembers, { + const { data, loading, error } = useQuery(GetOrganisationMemberDetail, { variables: { organisationId: organisation?.id, - role: null, // Fetch all roles + id: params.memberId, }, skip: !organisation || !userCanReadMembers, fetchPolicy: 'cache-and-network', }) - // Find the specific member from the list - const member: OrganisationMemberType | undefined = data?.organisationMembers.find( - (m: OrganisationMemberType) => m.id === params.memberId - ) + const member: OrganisationMemberType | undefined = data?.organisationMembers[0] if (loading || !organisation) { return ( @@ -224,7 +221,7 @@ export default function MemberDetail({ params }: { params: { team: string; membe
{member.appMemberships && member.appMemberships.length > 0 ? ( - member.appMemberships.map((app: AppType) => ( + member.appMemberships.map((app: AppMembershipType) => (
+ } + > + <> + + ) : ( +
+ Account already has access to all available apps. +
+ ))}
diff --git a/frontend/app/[team]/access/service-accounts/[account]/_components/DeleteServiceAccountTokenDialog.tsx b/frontend/app/[team]/access/service-accounts/[account]/_components/DeleteServiceAccountTokenDialog.tsx index b9504c8f2..fdfea69b8 100644 --- a/frontend/app/[team]/access/service-accounts/[account]/_components/DeleteServiceAccountTokenDialog.tsx +++ b/frontend/app/[team]/access/service-accounts/[account]/_components/DeleteServiceAccountTokenDialog.tsx @@ -60,7 +60,7 @@ export const DeleteServiceAccountTokenDialog = ({
Are you sure you want to delete this token?
-
diff --git a/frontend/app/[team]/access/service-accounts/[account]/page.tsx b/frontend/app/[team]/access/service-accounts/[account]/page.tsx index 0c2678f09..72e247ac8 100644 --- a/frontend/app/[team]/access/service-accounts/[account]/page.tsx +++ b/frontend/app/[team]/access/service-accounts/[account]/page.tsx @@ -219,30 +219,35 @@ export default function ServiceAccount({ params }: { params: { team: string; acc
{userCanReadAppMemberships && account.appMemberships?.length! > 0 && ( - + )} {userCanReadAppMemberships ? (
{account.appMemberships && account.appMemberships.length > 0 ? ( - account.appMemberships.map((app) => ( + account.appMemberships.map((appMembership) => (
{/* App Name and ID */}
- {app?.name} + {appMembership?.name}
- +
App ID: - - {app.id} + + + {appMembership.id} +
@@ -253,7 +258,7 @@ export default function ServiceAccount({ params }: { params: { team: string; acc Environments
- {app?.environments?.map((env) => env?.name).join(' + ')} + {appMembership?.environments?.map((env) => env?.name).join(' + ')}
@@ -261,7 +266,7 @@ export default function ServiceAccount({ params }: { params: { team: string; acc
-
diff --git a/frontend/app/[team]/apps/[app]/_components/AppSecretRow.tsx b/frontend/app/[team]/apps/[app]/_components/AppSecretRow.tsx index 5f467e471..a52bf279b 100644 --- a/frontend/app/[team]/apps/[app]/_components/AppSecretRow.tsx +++ b/frontend/app/[team]/apps/[app]/_components/AppSecretRow.tsx @@ -403,7 +403,7 @@ export const AppSecretRow = ({ > diff --git a/frontend/app/[team]/apps/[app]/_components/AppSecrets.tsx b/frontend/app/[team]/apps/[app]/_components/AppSecrets.tsx index 81ab13460..55f340dd8 100644 --- a/frontend/app/[team]/apps/[app]/_components/AppSecrets.tsx +++ b/frontend/app/[team]/apps/[app]/_components/AppSecrets.tsx @@ -183,6 +183,8 @@ export const AppSecrets = ({ team, app }: { team: string; app: string }) => { const searchRegex = new RegExp(searchQuery, 'i') return searchRegex.test(folder.name) }) + + const maxIndexDigits = filteredSecrets.length.toString().length ?? 1; const { data: syncsData } = useQuery(GetAppSyncStatus, { variables: { @@ -845,8 +847,9 @@ export const AppSecrets = ({ team, app }: { team: string; app: string }) => { className="sticky top-0 z-10 dark:bg-zinc-900/50 backdrop-blur-sm" > - - key + + + key {appEnvironments?.map((env: EnvironmentType) => ( [] } export const AddMemberDialog = ({ appId }: { appId: string }) => { + const searchParams = useSearchParams() + const preselectedAccountId = searchParams?.get('new') ?? null + const { keyring } = useContext(KeyringContext) const { activeOrganisation: organisation } = useContext(organisationContext) - const dialogRef = useRef<{ closeModal: () => void }>(null) + const dialogRef = useRef<{ openModal: () => void; closeModal: () => void }>(null) // Permissions const userCanReadAppMembers = organisation @@ -114,6 +118,7 @@ export const AddMemberDialog = ({ appId }: { appId: string }) => { const reset = () => { setSelectedMembers([]) } + const openModal = () => dialogRef.current?.openModal() const closeModal = () => dialogRef.current?.closeModal() const handleClose = () => { @@ -121,6 +126,34 @@ export const AddMemberDialog = ({ appId }: { appId: string }) => { reset() } + useEffect(() => { + if (preselectedAccountId && orgMembersData?.organisationMembers) { + // Check if user account is already added to the app + const isAlreadyAdded = data?.appUsers?.some( + (member: OrganisationMemberType) => member.id === preselectedAccountId + ) + + if (isAlreadyAdded) { + // Don't open dialog if already added + return + } + + const preselectedMember: OrganisationMemberType = orgMembersData?.organisationMembers.find( + (member: OrganisationMemberType) => member.id === preselectedAccountId + ) + + if (preselectedMember) { + setSelectedMembers([ + { + ...preselectedMember, + scope: [], + }, + ]) + openModal() + } + } + }, [preselectedAccountId, orgMembersData?.organisationMembers, data?.appUsers]) + const handleAddMembers = async (e: { preventDefault: () => void }) => { e.preventDefault() diff --git a/frontend/app/[team]/apps/[app]/access/members/_components/ManageUserAccessDialog.tsx b/frontend/app/[team]/apps/[app]/access/members/_components/ManageUserAccessDialog.tsx index 86d0896c7..7b0bac78f 100644 --- a/frontend/app/[team]/apps/[app]/access/members/_components/ManageUserAccessDialog.tsx +++ b/frontend/app/[team]/apps/[app]/access/members/_components/ManageUserAccessDialog.tsx @@ -18,6 +18,7 @@ import Link from 'next/link' import { arraysEqual, unwrapEnvSecretsForUser, wrapEnvSecretsForAccount } from '@/utils/crypto' import GenericDialog from '@/components/common/GenericDialog' import { sortEnvs } from '@/utils/secrets' +import { useSearchParams } from 'next/navigation' export const ManageUserAccessDialog = ({ member, @@ -29,8 +30,10 @@ export const ManageUserAccessDialog = ({ const { keyring } = useContext(KeyringContext) const { activeOrganisation: organisation } = useContext(organisationContext) const { data: session } = useSession() + const searchParams = useSearchParams() + const preselectedAccountId = searchParams?.get('manageAccount') ?? null - const dialogRef = useRef<{ closeModal: () => void }>(null) + const dialogRef = useRef<{ openModal: () => void; closeModal: () => void }>(null) // Permissions // AppMembers:update + Environments:read @@ -93,6 +96,12 @@ export const ManageUserAccessDialog = ({ setScope(sortEnvs(envScope)) }, [envScope]) + useEffect(() => { + if (preselectedAccountId && preselectedAccountId === member.id) { + dialogRef.current?.openModal() + } + }, [member.id, preselectedAccountId]) + const handleClose = () => { setScope(sortEnvs(envScope)) dialogRef.current?.closeModal() diff --git a/frontend/app/[team]/apps/[app]/access/service-accounts/_components/AddAccountDialog.tsx b/frontend/app/[team]/apps/[app]/access/service-accounts/_components/AddAccountDialog.tsx index d732baa34..942ca948a 100644 --- a/frontend/app/[team]/apps/[app]/access/service-accounts/_components/AddAccountDialog.tsx +++ b/frontend/app/[team]/apps/[app]/access/service-accounts/_components/AddAccountDialog.tsx @@ -140,11 +140,16 @@ export const AddAccountDialog = ({ appId }: { appId: string }) => { return } - const preselectedAccount = serviceAccountsData.serviceAccounts.find( + const preselectedAccount: ServiceAccountType = serviceAccountsData.serviceAccounts.find( (account: ServiceAccountType) => account.id === preselectedAccountId ) if (preselectedAccount) { - setSelectedAccounts(preselectedAccount) + setSelectedAccounts([ + { + ...preselectedAccount, + scope: [], + }, + ]) openModal() } } diff --git a/frontend/app/[team]/apps/[app]/access/service-accounts/_components/ManageAccountAccessDialog.tsx b/frontend/app/[team]/apps/[app]/access/service-accounts/_components/ManageAccountAccessDialog.tsx index 7105c08b7..969848aa0 100644 --- a/frontend/app/[team]/apps/[app]/access/service-accounts/_components/ManageAccountAccessDialog.tsx +++ b/frontend/app/[team]/apps/[app]/access/service-accounts/_components/ManageAccountAccessDialog.tsx @@ -19,6 +19,7 @@ import Link from 'next/link' import { arraysEqual, unwrapEnvSecretsForUser, wrapEnvSecretsForAccount } from '@/utils/crypto' import GenericDialog from '@/components/common/GenericDialog' import { sortEnvs } from '@/utils/secrets' +import { useSearchParams } from 'next/navigation' export const ManageAccountAccessDialog = ({ account, @@ -30,7 +31,10 @@ export const ManageAccountAccessDialog = ({ const { keyring } = useContext(KeyringContext) const { activeOrganisation: organisation } = useContext(organisationContext) - const dialogRef = useRef<{ closeModal: () => void }>(null) + const searchParams = useSearchParams() + const preselectedAccountId = searchParams?.get('manageAccount') ?? null + + const dialogRef = useRef<{ openModal: () => void; closeModal: () => void }>(null) // Permissions // AppMembers:update + Environments:read @@ -95,6 +99,12 @@ export const ManageAccountAccessDialog = ({ setScope(sortEnvs(envScope)) }, [envScope]) + useEffect(() => { + if (preselectedAccountId && preselectedAccountId === account.id) { + dialogRef.current?.openModal() + } + }, [account.id, preselectedAccountId]) + const handleClose = () => { setScope(sortEnvs(envScope)) dialogRef.current?.closeModal() diff --git a/frontend/app/[team]/apps/[app]/environments/[environment]/[[...path]]/page.tsx b/frontend/app/[team]/apps/[app]/environments/[environment]/[[...path]]/page.tsx index afb333093..b0b0f7e1f 100644 --- a/frontend/app/[team]/apps/[app]/environments/[environment]/[[...path]]/page.tsx +++ b/frontend/app/[team]/apps/[app]/environments/[environment]/[[...path]]/page.tsx @@ -527,6 +527,8 @@ export default function EnvironmentPath({ const filteredAndSortedSecrets = sortSecrets(filteredSecrets, sort) + const maxIndexDigits = filteredAndSortedSecrets.length.toString().length ?? 1; + const downloadEnvFile = () => { const envContent = serverSecrets .map((secret) => { @@ -971,7 +973,8 @@ export default function EnvironmentPath({ {(clientSecrets.length > 0 || folders.length > 0) && (
-
+
+
key
@@ -1018,11 +1021,15 @@ export default function EnvironmentPath({ className={clsx( 'flex items-center gap-2 py-1 px-3 rounded-md', secretToHighlight === secret.id && - 'ring-1 ring-inset ring-emerald-100 dark:ring-emerald-900 bg-emerald-400/10' + 'ring-1 ring-inset ring-emerald-100 dark:ring-emerald-900 bg-emerald-400/20' )} key={secret.id} > - {index + 1} + + {index + 1} + void }) { useEffect(() => { - // Log the error to an error reporting service console.error(error) }, [error]) return ( -
+
-

Something went wrong!

- -
+ +
+
+

+ Something went wrong! +

+

+ {error.name}: {error.message || 'An unexpected error occurred'} +

+
+ +
+ ) } diff --git a/frontend/app/lockbox/[boxId]/page.tsx b/frontend/app/lockbox/[boxId]/page.tsx index dc91e960b..18dc65c47 100644 --- a/frontend/app/lockbox/[boxId]/page.tsx +++ b/frontend/app/lockbox/[boxId]/page.tsx @@ -12,7 +12,7 @@ export default async function Lockbox({ params }: { params: { boxId: string } })
Phase Lockbox
- You've recieved a secret via Phase Lockbox, secured with Zero-Trust encryption. + You've received a secret via Phase Lockbox, secured with Zero-Trust encryption. Click the View button to decrypt and view this secret.
diff --git a/frontend/components/common/CommandPalette.tsx b/frontend/components/common/CommandPalette.tsx index 8d18616f2..fb1869959 100644 --- a/frontend/components/common/CommandPalette.tsx +++ b/frontend/components/common/CommandPalette.tsx @@ -29,6 +29,11 @@ import { ThemeContext } from '@/contexts/themeContext' import { BsListColumnsReverse } from 'react-icons/bs' import { FaArrowsRotate, FaCodeMerge, FaListCheck } from 'react-icons/fa6' import { userHasPermission } from '@/utils/access/permissions' +import { KeyringContext } from '@/contexts/keyringContext' +import { useSecretSearch } from '@/hooks/useSecretSearch' +import debounce from 'lodash/debounce' +import Spinner from './Spinner' +import clsx from 'clsx' type CommandItem = { id: string @@ -51,6 +56,7 @@ const CommandPalette: React.FC = () => { const router = useRouter() const { activeOrganisation, organisations } = useContext(organisationContext) const { theme, setTheme } = useContext(ThemeContext) + const { keyring } = useContext(KeyringContext) // Permission checks const userCanReadApps = userHasPermission(activeOrganisation?.role?.permissions, 'Apps', 'read') @@ -251,6 +257,32 @@ const CommandPalette: React.FC = () => { ], })) || [] + // Debounce helper for query input + const debouncedSetQuery = React.useMemo(() => debounce((val: string) => setQuery(val), 250), []) + React.useEffect(() => { + return () => { + debouncedSetQuery.cancel() + } + }, [debouncedSetQuery]) + + // Secret search hook (fetches/decrypts keys only when query is set) + const { results: secretResults, loading: secretLoading } = useSecretSearch( + query, + activeOrganisation?.id, + keyring + ) + + const secretCommands: CommandItem[] = secretResults.map((secret) => ({ + id: secret.id, + name: secret.key, + description: `${secret.appName} • ${secret.envName} • ${secret.path}`, + icon: , + action: () => + handleNavigation( + `/${activeOrganisation?.name}/apps/${secret.appId}/environments/${secret.envId}${secret.path === '/' ? '' : secret.path}?secret=${secret.id}` + ), + })) + const allCommands: CommandGroup[] = [ { name: 'Actions', @@ -262,6 +294,15 @@ const CommandPalette: React.FC = () => { icon: , items: navigationCommands, }, + ...(secretCommands.length > 0 + ? [ + { + name: 'Secrets', + icon: , + items: secretCommands, + }, + ] + : []), ...(appCommands.length > 0 ? appCommands : []), { name: 'Resources', @@ -325,6 +366,27 @@ const CommandPalette: React.FC = () => { }, 100) } + function highlightMatch(text: string, query: string) { + if (!query) return [text] + + const lowerText = text.toLowerCase() + const lowerQuery = query.toLowerCase() + const matchIndex = lowerText.indexOf(lowerQuery) + + if (matchIndex === -1) return [text] + + return [ + text.slice(0, matchIndex), + + {text.slice(matchIndex, matchIndex + query.length)} + , + text.slice(matchIndex + query.length), + ] + } + return ( <>
{filteredCommands.length > 0 && ( @@ -416,10 +483,18 @@ const CommandPalette: React.FC = () => { {item.icon}
-
- {item.name} +
+ {highlightMatch(item.name, query)} +
+ +
+ {highlightMatch(item.description, query)}
-
{item.description}
diff --git a/frontend/graphql/queries/organisation/getOrganisationMembers.gql b/frontend/graphql/queries/organisation/getOrganisationMembers.gql index 6a48853ba..98dc029c6 100644 --- a/frontend/graphql/queries/organisation/getOrganisationMembers.gql +++ b/frontend/graphql/queries/organisation/getOrganisationMembers.gql @@ -15,26 +15,5 @@ query GetOrganisationMembers($organisationId: ID!, $role: [String]) { createdAt lastLogin self - appMemberships { - id - name - sseEnabled - environments { - id - name - } - } - tokens { - id - name - createdAt - expiresAt - } - networkPolicies { - id - name - allowedIps - isGlobal - } } } diff --git a/frontend/graphql/queries/secrets/getAppSecrets.gql b/frontend/graphql/queries/secrets/getAppSecrets.gql index 839858339..015a57fdc 100644 --- a/frontend/graphql/queries/secrets/getAppSecrets.gql +++ b/frontend/graphql/queries/secrets/getAppSecrets.gql @@ -1,4 +1,4 @@ -query GetAppSecrets($appId: ID!, $memberId: ID, $memberType: MemberType) { +query GetAppSecrets($appId: ID!, $memberId: ID, $memberType: MemberType, $path: String) { appEnvironments( appId: $appId environmentId: null @@ -29,7 +29,7 @@ query GetAppSecrets($appId: ID!, $memberId: ID, $memberType: MemberType) { name path } - secrets { + secrets(path: $path) { id key value diff --git a/frontend/graphql/queries/secrets/getOrgSecretKeys.gql b/frontend/graphql/queries/secrets/getOrgSecretKeys.gql new file mode 100644 index 000000000..011d8b830 --- /dev/null +++ b/frontend/graphql/queries/secrets/getOrgSecretKeys.gql @@ -0,0 +1,17 @@ +query GetOrgSecretKeys($organisationId: ID!) { + apps(organisationId: $organisationId) { + id + name + environments { + id + name + wrappedSeed + wrappedSalt + secrets { + id + key + path + } + } + } +} diff --git a/frontend/graphql/queries/users/getOrganisationMemberDetail.gql b/frontend/graphql/queries/users/getOrganisationMemberDetail.gql new file mode 100644 index 000000000..b128f9895 --- /dev/null +++ b/frontend/graphql/queries/users/getOrganisationMemberDetail.gql @@ -0,0 +1,40 @@ +query GetOrganisationMemberDetail($organisationId: ID!, $id: ID) { + organisationMembers(organisationId: $organisationId, memberId: $id) { + id + role { + id + name + description + permissions + color + } + identityKey + email + fullName + avatarUrl + createdAt + lastLogin + self + appMemberships { + id + name + sseEnabled + environments { + id + name + } + } + tokens { + id + name + createdAt + expiresAt + } + networkPolicies { + id + name + allowedIps + isGlobal + } + } +} diff --git a/frontend/hooks/useSecretSearch.ts b/frontend/hooks/useSecretSearch.ts new file mode 100644 index 000000000..eded77014 --- /dev/null +++ b/frontend/hooks/useSecretSearch.ts @@ -0,0 +1,108 @@ +import { useApolloClient } from '@apollo/client' +import { useEffect, useRef, useState } from 'react' +import { unwrapEnvSecretsForUser } from '@/utils/crypto' +import { decryptAsymmetric } from '@/utils/crypto/general' +import GetOrgSecretKeys from '@/graphql/queries/secrets/getOrgSecretKeys.gql' +import { OrganisationKeyring } from '@/utils/crypto' + +interface SecretMeta { + id: string + key: string + appId: string + envId: string + path: string + appName: string + envName: string +} + +interface UseSecretSearchReturn { + results: SecretMeta[] + loading: boolean +} + +// Fetches and decrypts secret keys once per-organisaton on first query, then caches. +export const useSecretSearch = ( + query: string, + organisationId: string | undefined | null, + keyring: OrganisationKeyring | null +): UseSecretSearchReturn => { + const client = useApolloClient() + const cacheRef = useRef(null) + const [results, setResults] = useState([]) + const [loading, setLoading] = useState(false) + + useEffect(() => { + let cancelled = false + + const executeSearch = async () => { + // Simple normalisation: remove spaces/underscores, lowercase. + const normalize = (str: string) => str.replace(/[\\s_]/g, '').toLowerCase() + const normalizedQuery = normalize(query) + + if (!normalizedQuery) { + setResults([]) + return + } + if (!organisationId || !keyring) return + + if (!cacheRef.current) { + setLoading(true) + const collected: SecretMeta[] = [] + + try { + const { data } = await client.query({ + query: GetOrgSecretKeys, + variables: { organisationId }, + fetchPolicy: 'network-only', + }) + + for (const app of data.apps) { + for (const env of app.environments) { + const { publicKey, privateKey } = await unwrapEnvSecretsForUser( + env.wrappedSeed, + env.wrappedSalt, + keyring + ) + + for (const secret of env.secrets) { + const decryptedKey = await decryptAsymmetric( + secret.key, + privateKey, + publicKey + ) + collected.push({ + id: secret.id, + key: decryptedKey, + appId: app.id, + envId: env.id, + path: secret.path, + appName: app.name, + envName: env.name, + }) + } + } + } + } catch (error) { + console.error('Secret key fetch failed', error) + } + + if (cancelled) return + cacheRef.current = collected + setLoading(false) + } + + const filtered = cacheRef.current!.filter((s) => + normalize(s.key).includes(normalizedQuery) + ) + setResults(filtered) + } + + executeSearch() + + return () => { + cancelled = true + } + }, [query, organisationId, keyring, client]) + + return { results, loading } +} diff --git a/img/aws-eks.svg b/img/aws-eks.svg new file mode 100644 index 000000000..071b640ff --- /dev/null +++ b/img/aws-eks.svg @@ -0,0 +1 @@ +Amazon EKS \ No newline at end of file diff --git a/img/console-ui.mp4 b/img/console-ui.mp4 deleted file mode 100644 index 8cfa30526..000000000 Binary files a/img/console-ui.mp4 and /dev/null differ diff --git a/img/terraform.svg b/img/terraform.svg new file mode 100644 index 000000000..f4f3dbe0e --- /dev/null +++ b/img/terraform.svg @@ -0,0 +1 @@ +Terraform \ No newline at end of file