From bea0ff6e05a4de73a5db625d4ae181a015b50855 Mon Sep 17 00:00:00 2001
From: Maidul Islam
Date: Thu, 17 Nov 2022 17:54:35 -0500
Subject: [PATCH] Add frontend, backend and CLI
---
.env.example | 70 +
.github/workflows/release_build.yml | 40 +
.gitignore | 46 +-
.goreleaser.yaml | 107 +
CODE_OF_CONDUCT.md | 128 +
CONTRIBUTING.md | 5 +
Makefile | 14 +
README.md | 117 +-
SECURITY.md | 9 +
backend/.dockerignore | 11 +
backend/.eslintignore | 2 +
backend/.eslintrc | 18 +
backend/.prettierrc | 7 +
backend/Dockerfile | 12 +
backend/environment.d.ts | 37 +
backend/img/dashboard.png | Bin 0 -> 504493 bytes
backend/nodemon.json | 6 +
backend/package-lock.json | 19021 ++++++++++++++++
backend/package.json | 72 +
backend/src/config/index.ts | 63 +
backend/src/controllers/authController.ts | 224 +
backend/src/controllers/index.ts | 33 +
.../controllers/integrationAuthController.ts | 153 +
.../src/controllers/integrationController.ts | 158 +
backend/src/controllers/keyController.ts | 109 +
.../src/controllers/membershipController.ts | 236 +
.../controllers/membershipOrgController.ts | 269 +
.../src/controllers/organizationController.ts | 399 +
backend/src/controllers/passwordController.ts | 189 +
backend/src/controllers/secretController.ts | 226 +
.../src/controllers/serviceTokenController.ts | 75 +
backend/src/controllers/signupController.ts | 287 +
backend/src/controllers/stripeController.ts | 40 +
.../src/controllers/userActionController.ts | 70 +
backend/src/controllers/userController.ts | 13 +
.../src/controllers/workspaceController.ts | 337 +
backend/src/ee/LICENSE | 36 +
backend/src/ee/controllers/index.ts | 5 +
.../src/ee/controllers/stripeController.ts | 40 +
backend/src/ee/helpers/license.ts | 21 +
.../src/ee/middleware/requireLicenseAuth.ts | 23 +
backend/src/ee/routes/stripe.ts | 7 +
backend/src/ee/variables.ts | 0
backend/src/helpers/auth.ts | 102 +
backend/src/helpers/integration.ts | 0
backend/src/helpers/integrationAuth.ts | 174 +
backend/src/helpers/key.ts | 62 +
backend/src/helpers/membership.ts | 100 +
backend/src/helpers/membershipOrg.ts | 120 +
backend/src/helpers/nodemailer.ts | 58 +
backend/src/helpers/organization.ts | 168 +
backend/src/helpers/rateLimiter.ts | 35 +
backend/src/helpers/secret.ts | 303 +
backend/src/helpers/signup.ts | 124 +
backend/src/helpers/user.ts | 88 +
backend/src/helpers/workspace.ts | 62 +
backend/src/index.ts | 90 +
backend/src/json/integrations.json | 50 +
backend/src/middleware/index.ts | 19 +
backend/src/middleware/requireAuth.ts | 51 +
.../src/middleware/requireIntegrationAuth.ts | 76 +
.../requireIntegrationAuthorizationAuth.ts | 72 +
.../src/middleware/requireOrganizationAuth.ts | 54 +
.../src/middleware/requireServiceTokenAuth.ts | 56 +
backend/src/middleware/requireSignupAuth.ts | 52 +
.../src/middleware/requireWorkspaceAuth.ts | 60 +
backend/src/middleware/validateRequest.ts | 31 +
backend/src/models/backupPrivateKey.ts | 56 +
backend/src/models/incidentContactOrg.ts | 31 +
backend/src/models/index.ts | 45 +
backend/src/models/integration.ts | 61 +
backend/src/models/integrationAuth.ts | 67 +
backend/src/models/key.ts | 45 +
backend/src/models/membership.ts | 46 +
backend/src/models/membershipOrg.ts | 47 +
backend/src/models/organization.ts | 26 +
backend/src/models/secret.ts | 89 +
backend/src/models/serviceToken.ts | 64 +
backend/src/models/token.ts | 28 +
backend/src/models/user.ts | 65 +
backend/src/models/userAction.ts | 28 +
backend/src/models/workspace.ts | 23 +
backend/src/routes/auth.ts | 35 +
backend/src/routes/index.ts | 35 +
backend/src/routes/integration.ts | 53 +
backend/src/routes/integrationAuth.ts | 52 +
backend/src/routes/inviteOrg.ts | 24 +
backend/src/routes/key.ts | 39 +
backend/src/routes/membership.ts | 31 +
backend/src/routes/membershipOrg.ts | 24 +
backend/src/routes/organization.ts | 137 +
backend/src/routes/password.ts | 44 +
backend/src/routes/secret.ts | 53 +
backend/src/routes/serviceToken.ts | 40 +
backend/src/routes/signup.ts | 60 +
backend/src/routes/stripe.ts | 7 +
backend/src/routes/user.ts | 8 +
backend/src/routes/userAction.ts | 23 +
backend/src/routes/workspace.ts | 133 +
.../templates/emailVerification.handlebars | 15 +
.../organizationInvitation.handlebars | 18 +
.../templates/workspaceInvitation.handlebars | 16 +
backend/src/types/express/index.d.ts | 19 +
backend/src/utils/aes-gcm.ts | 43 +
backend/src/utils/crypto.ts | 146 +
backend/src/variables.ts | 60 +
backend/tsconfig.json | 23 +
cli/.gitignore | 2 +
cli/README.md | 102 +
cli/go.mod | 26 +
cli/go.sum | 58 +
cli/goreleaser.dockerfile | 4 +
cli/infisical-cli.repo | 5 +
cli/main.go | 10 +
cli/packages/cmd/init.go | 130 +
cli/packages/cmd/logging.go | 27 +
cli/packages/cmd/login.go | 242 +
cli/packages/cmd/root.go | 34 +
cli/packages/cmd/run.go | 147 +
cli/packages/models/api.go | 130 +
cli/packages/models/cli.go | 21 +
cli/packages/srp/client.go | 140 +
cli/packages/srp/params.go | 95 +
cli/packages/srp/server.go | 104 +
cli/packages/srp/srp.go | 103 +
cli/packages/srp/util.go | 48 +
cli/packages/util/common.go | 29 +
cli/packages/util/config.go | 92 +
cli/packages/util/credentials.go | 99 +
cli/packages/util/crypto.go | 31 +
cli/packages/util/secrets.go | 205 +
cli/scripts/install.sh | 97 +
cli/upload_to_cloudfront.sh | 14 +
docker-compose.dev.yml | 66 +
docker-compose.prod.yml | 57 +
docker-compose.yml | 17 +
frontend/.dockerignore | 3 +
frontend/.gitignore | 34 +
frontend/.prettierrc | 4 +
frontend/Dockerfile.dev | 21 +
frontend/Dockerfile.prod | 21 +
frontend/README.md | 20 +
frontend/components/RouteGuard.js | 82 +
frontend/components/aes-256-gcm.js | 63 +
frontend/components/analytics/posthog.js | 13 +
frontend/components/basic/Error.js | 19 +
frontend/components/basic/InputField.js | 130 +
frontend/components/basic/Listbox.js | 108 +
frontend/components/basic/buttons/Button.js | 111 +
.../basic/dialog/AddIncidentContactDialog.js | 95 +
.../basic/dialog/AddProjectMemberDialog.js | 150 +
.../basic/dialog/AddServiceTokenDialog.js | 231 +
.../components/basic/dialog/AddUserDialog.js | 149 +
.../basic/dialog/AddWorkspaceDialog.js | 104 +
.../basic/dialog/DeleteUserDialog.js | 77 +
frontend/components/basic/layout.js | 318 +
.../basic/popups/BottomRightPopup.js | 41 +
frontend/components/basic/table/Checkbox.js | 28 +
.../basic/table/ServiceTokenTable.js | 81 +
frontend/components/basic/table/UserTable.js | 267 +
frontend/components/billing/Card.js | 72 +
frontend/components/billing/Plan.js | 82 +
.../dashboard/DashboardInputField.js | 68 +
frontend/components/dashboard/DropZone.js | 187 +
.../components/navigation/NavBarDashboard.js | 311 +
frontend/components/navigation/NavHeader.js | 47 +
.../components/utilities/SecurityClient.js | 29 +
frontend/components/utilities/attemptLogin.js | 182 +
.../components/utilities/changePassword.js | 109 +
.../utilities/checks/PasswordCheck.js | 65 +
frontend/components/utilities/crypto.js | 105 +
frontend/components/utilities/csp.js | 0
frontend/components/utilities/file.js | 47 +
.../components/utilities/generateBackupPDF.js | 135 +
.../utilities/getSecretsForProject.js | 106 +
.../components/utilities/issueBackupKey.js | 96 +
frontend/components/utilities/pushKeys.js | 109 +
.../utilities/pushKeysIntegration.js | 77 +
frontend/components/utilities/randomId.js | 25 +
frontend/const.js | 20 +
frontend/next.config.js | 63 +
frontend/package-lock.json | 8007 +++++++
frontend/package.json | 62 +
frontend/pages/_app.js | 71 +
frontend/pages/api/auth/ChangePassword2.js | 33 +
frontend/pages/api/auth/CheckAuth.js | 27 +
.../api/auth/CheckEmailVerificationCode.js | 22 +
.../auth/CompleteAccountInformationSignup.js | 52 +
.../CompleteAccountInformationSignupInvite.js | 49 +
.../pages/api/auth/IssueBackupPrivateKey.js | 32 +
frontend/pages/api/auth/Login1.js | 22 +
frontend/pages/api/auth/Login2.js | 31 +
frontend/pages/api/auth/Logout.js | 36 +
frontend/pages/api/auth/SRP1.js | 28 +
.../pages/api/auth/SendVerificationEmail.js | 19 +
frontend/pages/api/auth/Token.js | 20 +
frontend/pages/api/auth/VerifySignupInvite.js | 22 +
frontend/pages/api/auth/publicKeyInfisical.js | 18 +
frontend/pages/api/files/GetSecrets.js | 33 +
frontend/pages/api/files/UploadSecrets.js | 32 +
.../integrations/ChangeHerokuConfigVars.js | 24 +
.../api/integrations/DeleteIntegration.js | 25 +
.../api/integrations/DeleteIntegrationAuth.js | 25 +
.../api/integrations/GetIntegrationApps.js | 20 +
.../pages/api/integrations/GetIntegrations.js | 20 +
.../api/integrations/StartIntegration.js | 32 +
.../api/integrations/authorizeIntegration.js | 30 +
.../getWorkspaceAuthorizations.js | 25 +
.../integrations/getWorkspaceIntegrations.js | 25 +
frontend/pages/api/organization/GetOrg.js | 26 +
.../pages/api/organization/GetOrgProjects.js | 26 +
.../api/organization/GetOrgSubscription.js | 26 +
.../api/organization/GetOrgUserProjects.js | 26 +
.../pages/api/organization/GetOrgUsers.js | 26 +
.../pages/api/organization/StripeRedirect.js | 26 +
.../api/organization/addIncidentContact.js | 28 +
.../pages/api/organization/addUserToOrg.js | 30 +
.../api/organization/deleteIncidentContact.js | 28 +
.../deleteUserFromOrganization.js | 25 +
.../api/organization/getIncidentContacts.js | 25 +
frontend/pages/api/organization/getOrgs.js | 26 +
frontend/pages/api/organization/renameOrg.js | 29 +
.../pages/api/serviceToken/addServiceToken.js | 34 +
.../api/serviceToken/getServiceTokens.js | 25 +
frontend/pages/api/user/getUser.js | 26 +
.../pages/api/userActions/checkUserAction.js | 30 +
.../api/userActions/registerUserAction.js | 28 +
.../pages/api/workspace/addUserToWorkspace.js | 29 +
.../workspace/changeUserRoleInWorkspace.js | 29 +
.../pages/api/workspace/createWorkspace.js | 29 +
.../api/workspace/deleteUserFromWorkspace.js | 25 +
.../pages/api/workspace/deleteWorkspace.js | 25 +
.../pages/api/workspace/getLatestFileKey.js | 25 +
.../pages/api/workspace/getWorkspaceInfo.js | 26 +
.../pages/api/workspace/getWorkspaceKeys.js | 26 +
.../pages/api/workspace/getWorkspaceUsers.js | 26 +
frontend/pages/api/workspace/getWorkspaces.js | 26 +
.../pages/api/workspace/renameWorkspace.js | 29 +
frontend/pages/api/workspace/uploadKeys.js | 35 +
frontend/pages/dashboard.js | 31 +
frontend/pages/dashboard/[id].js | 686 +
frontend/pages/heroku.js | 35 +
frontend/pages/index.js | 15 +
frontend/pages/integrations/[id].js | 278 +
frontend/pages/login.js | 132 +
frontend/pages/noprojects.js | 20 +
frontend/pages/requestnewinvite.js | 22 +
frontend/pages/settings/billing/[id].js | 102 +
frontend/pages/settings/org/[id].js | 390 +
frontend/pages/settings/personal/[id].js | 241 +
frontend/pages/settings/project/[id].js | 281 +
frontend/pages/signup.js | 483 +
frontend/pages/signupinvite.js | 317 +
frontend/pages/users/[id].js | 210 +
frontend/postcss.config.js | 6 +
frontend/public/images/biglogo.png | Bin 0 -> 85230 bytes
frontend/public/images/blog1.png | Bin 0 -> 83791 bytes
frontend/public/images/blog3.png | Bin 0 -> 1444419 bytes
frontend/public/images/envelope.svg | 15 +
.../integrations/Amazon Web Services.png | Bin 0 -> 15275 bytes
.../public/images/integrations/Circle CI.png | Bin 0 -> 8027 bytes
.../images/integrations/Digital Ocean.png | Bin 0 -> 5873 bytes
.../integrations/Google Cloud Platform.png | Bin 0 -> 18032 bytes
.../public/images/integrations/Heroku.png | Bin 0 -> 36446 bytes
.../images/integrations/Microsoft Azure.png | Bin 0 -> 9323 bytes
.../public/images/integrations/Netlify.png | Bin 0 -> 91054 bytes
.../public/images/integrations/Travis CI.png | Bin 0 -> 37526 bytes
frontend/public/images/loading/loading.gif | Bin 0 -> 1341944 bytes
.../public/images/loading/loadingblack.gif | Bin 0 -> 522609 bytes
frontend/public/images/logotransparent.png | Bin 0 -> 23662 bytes
frontend/public/infisical.ico | Bin 0 -> 431768 bytes
frontend/public/vercel.svg | 4 +
frontend/styles/globals.css | 3 +
frontend/tailwind.config.js | 1686 ++
frontend/yarn.lock | 2810 +++
nginx/default.conf | 32 +
276 files changed, 50230 insertions(+), 72 deletions(-)
create mode 100644 .env.example
create mode 100644 .github/workflows/release_build.yml
create mode 100644 .goreleaser.yaml
create mode 100644 CODE_OF_CONDUCT.md
create mode 100644 CONTRIBUTING.md
create mode 100644 Makefile
create mode 100644 SECURITY.md
create mode 100644 backend/.dockerignore
create mode 100644 backend/.eslintignore
create mode 100644 backend/.eslintrc
create mode 100644 backend/.prettierrc
create mode 100644 backend/Dockerfile
create mode 100644 backend/environment.d.ts
create mode 100644 backend/img/dashboard.png
create mode 100644 backend/nodemon.json
create mode 100644 backend/package-lock.json
create mode 100644 backend/package.json
create mode 100644 backend/src/config/index.ts
create mode 100644 backend/src/controllers/authController.ts
create mode 100644 backend/src/controllers/index.ts
create mode 100644 backend/src/controllers/integrationAuthController.ts
create mode 100644 backend/src/controllers/integrationController.ts
create mode 100644 backend/src/controllers/keyController.ts
create mode 100644 backend/src/controllers/membershipController.ts
create mode 100644 backend/src/controllers/membershipOrgController.ts
create mode 100644 backend/src/controllers/organizationController.ts
create mode 100644 backend/src/controllers/passwordController.ts
create mode 100644 backend/src/controllers/secretController.ts
create mode 100644 backend/src/controllers/serviceTokenController.ts
create mode 100644 backend/src/controllers/signupController.ts
create mode 100644 backend/src/controllers/stripeController.ts
create mode 100644 backend/src/controllers/userActionController.ts
create mode 100644 backend/src/controllers/userController.ts
create mode 100644 backend/src/controllers/workspaceController.ts
create mode 100644 backend/src/ee/LICENSE
create mode 100644 backend/src/ee/controllers/index.ts
create mode 100644 backend/src/ee/controllers/stripeController.ts
create mode 100644 backend/src/ee/helpers/license.ts
create mode 100644 backend/src/ee/middleware/requireLicenseAuth.ts
create mode 100644 backend/src/ee/routes/stripe.ts
create mode 100644 backend/src/ee/variables.ts
create mode 100644 backend/src/helpers/auth.ts
create mode 100644 backend/src/helpers/integration.ts
create mode 100644 backend/src/helpers/integrationAuth.ts
create mode 100644 backend/src/helpers/key.ts
create mode 100644 backend/src/helpers/membership.ts
create mode 100644 backend/src/helpers/membershipOrg.ts
create mode 100644 backend/src/helpers/nodemailer.ts
create mode 100644 backend/src/helpers/organization.ts
create mode 100644 backend/src/helpers/rateLimiter.ts
create mode 100644 backend/src/helpers/secret.ts
create mode 100644 backend/src/helpers/signup.ts
create mode 100644 backend/src/helpers/user.ts
create mode 100644 backend/src/helpers/workspace.ts
create mode 100644 backend/src/index.ts
create mode 100644 backend/src/json/integrations.json
create mode 100644 backend/src/middleware/index.ts
create mode 100644 backend/src/middleware/requireAuth.ts
create mode 100644 backend/src/middleware/requireIntegrationAuth.ts
create mode 100644 backend/src/middleware/requireIntegrationAuthorizationAuth.ts
create mode 100644 backend/src/middleware/requireOrganizationAuth.ts
create mode 100644 backend/src/middleware/requireServiceTokenAuth.ts
create mode 100644 backend/src/middleware/requireSignupAuth.ts
create mode 100644 backend/src/middleware/requireWorkspaceAuth.ts
create mode 100644 backend/src/middleware/validateRequest.ts
create mode 100644 backend/src/models/backupPrivateKey.ts
create mode 100644 backend/src/models/incidentContactOrg.ts
create mode 100644 backend/src/models/index.ts
create mode 100644 backend/src/models/integration.ts
create mode 100644 backend/src/models/integrationAuth.ts
create mode 100644 backend/src/models/key.ts
create mode 100644 backend/src/models/membership.ts
create mode 100644 backend/src/models/membershipOrg.ts
create mode 100644 backend/src/models/organization.ts
create mode 100644 backend/src/models/secret.ts
create mode 100644 backend/src/models/serviceToken.ts
create mode 100644 backend/src/models/token.ts
create mode 100644 backend/src/models/user.ts
create mode 100644 backend/src/models/userAction.ts
create mode 100644 backend/src/models/workspace.ts
create mode 100644 backend/src/routes/auth.ts
create mode 100644 backend/src/routes/index.ts
create mode 100644 backend/src/routes/integration.ts
create mode 100644 backend/src/routes/integrationAuth.ts
create mode 100644 backend/src/routes/inviteOrg.ts
create mode 100644 backend/src/routes/key.ts
create mode 100644 backend/src/routes/membership.ts
create mode 100644 backend/src/routes/membershipOrg.ts
create mode 100644 backend/src/routes/organization.ts
create mode 100644 backend/src/routes/password.ts
create mode 100644 backend/src/routes/secret.ts
create mode 100644 backend/src/routes/serviceToken.ts
create mode 100644 backend/src/routes/signup.ts
create mode 100644 backend/src/routes/stripe.ts
create mode 100644 backend/src/routes/user.ts
create mode 100644 backend/src/routes/userAction.ts
create mode 100644 backend/src/routes/workspace.ts
create mode 100644 backend/src/templates/emailVerification.handlebars
create mode 100644 backend/src/templates/organizationInvitation.handlebars
create mode 100644 backend/src/templates/workspaceInvitation.handlebars
create mode 100644 backend/src/types/express/index.d.ts
create mode 100644 backend/src/utils/aes-gcm.ts
create mode 100644 backend/src/utils/crypto.ts
create mode 100644 backend/src/variables.ts
create mode 100644 backend/tsconfig.json
create mode 100644 cli/.gitignore
create mode 100644 cli/README.md
create mode 100644 cli/go.mod
create mode 100644 cli/go.sum
create mode 100644 cli/goreleaser.dockerfile
create mode 100644 cli/infisical-cli.repo
create mode 100644 cli/main.go
create mode 100644 cli/packages/cmd/init.go
create mode 100644 cli/packages/cmd/logging.go
create mode 100644 cli/packages/cmd/login.go
create mode 100644 cli/packages/cmd/root.go
create mode 100644 cli/packages/cmd/run.go
create mode 100644 cli/packages/models/api.go
create mode 100644 cli/packages/models/cli.go
create mode 100644 cli/packages/srp/client.go
create mode 100644 cli/packages/srp/params.go
create mode 100644 cli/packages/srp/server.go
create mode 100644 cli/packages/srp/srp.go
create mode 100644 cli/packages/srp/util.go
create mode 100644 cli/packages/util/common.go
create mode 100644 cli/packages/util/config.go
create mode 100644 cli/packages/util/credentials.go
create mode 100644 cli/packages/util/crypto.go
create mode 100644 cli/packages/util/secrets.go
create mode 100755 cli/scripts/install.sh
create mode 100755 cli/upload_to_cloudfront.sh
create mode 100644 docker-compose.dev.yml
create mode 100644 docker-compose.prod.yml
create mode 100644 docker-compose.yml
create mode 100644 frontend/.dockerignore
create mode 100644 frontend/.gitignore
create mode 100644 frontend/.prettierrc
create mode 100644 frontend/Dockerfile.dev
create mode 100644 frontend/Dockerfile.prod
create mode 100644 frontend/README.md
create mode 100644 frontend/components/RouteGuard.js
create mode 100644 frontend/components/aes-256-gcm.js
create mode 100644 frontend/components/analytics/posthog.js
create mode 100644 frontend/components/basic/Error.js
create mode 100644 frontend/components/basic/InputField.js
create mode 100644 frontend/components/basic/Listbox.js
create mode 100644 frontend/components/basic/buttons/Button.js
create mode 100644 frontend/components/basic/dialog/AddIncidentContactDialog.js
create mode 100644 frontend/components/basic/dialog/AddProjectMemberDialog.js
create mode 100644 frontend/components/basic/dialog/AddServiceTokenDialog.js
create mode 100644 frontend/components/basic/dialog/AddUserDialog.js
create mode 100644 frontend/components/basic/dialog/AddWorkspaceDialog.js
create mode 100644 frontend/components/basic/dialog/DeleteUserDialog.js
create mode 100644 frontend/components/basic/layout.js
create mode 100644 frontend/components/basic/popups/BottomRightPopup.js
create mode 100644 frontend/components/basic/table/Checkbox.js
create mode 100644 frontend/components/basic/table/ServiceTokenTable.js
create mode 100644 frontend/components/basic/table/UserTable.js
create mode 100644 frontend/components/billing/Card.js
create mode 100644 frontend/components/billing/Plan.js
create mode 100644 frontend/components/dashboard/DashboardInputField.js
create mode 100644 frontend/components/dashboard/DropZone.js
create mode 100644 frontend/components/navigation/NavBarDashboard.js
create mode 100644 frontend/components/navigation/NavHeader.js
create mode 100644 frontend/components/utilities/SecurityClient.js
create mode 100644 frontend/components/utilities/attemptLogin.js
create mode 100644 frontend/components/utilities/changePassword.js
create mode 100644 frontend/components/utilities/checks/PasswordCheck.js
create mode 100644 frontend/components/utilities/crypto.js
create mode 100644 frontend/components/utilities/csp.js
create mode 100644 frontend/components/utilities/file.js
create mode 100644 frontend/components/utilities/generateBackupPDF.js
create mode 100644 frontend/components/utilities/getSecretsForProject.js
create mode 100644 frontend/components/utilities/issueBackupKey.js
create mode 100644 frontend/components/utilities/pushKeys.js
create mode 100644 frontend/components/utilities/pushKeysIntegration.js
create mode 100644 frontend/components/utilities/randomId.js
create mode 100644 frontend/const.js
create mode 100644 frontend/next.config.js
create mode 100644 frontend/package-lock.json
create mode 100644 frontend/package.json
create mode 100644 frontend/pages/_app.js
create mode 100644 frontend/pages/api/auth/ChangePassword2.js
create mode 100644 frontend/pages/api/auth/CheckAuth.js
create mode 100644 frontend/pages/api/auth/CheckEmailVerificationCode.js
create mode 100644 frontend/pages/api/auth/CompleteAccountInformationSignup.js
create mode 100644 frontend/pages/api/auth/CompleteAccountInformationSignupInvite.js
create mode 100644 frontend/pages/api/auth/IssueBackupPrivateKey.js
create mode 100644 frontend/pages/api/auth/Login1.js
create mode 100644 frontend/pages/api/auth/Login2.js
create mode 100644 frontend/pages/api/auth/Logout.js
create mode 100644 frontend/pages/api/auth/SRP1.js
create mode 100644 frontend/pages/api/auth/SendVerificationEmail.js
create mode 100644 frontend/pages/api/auth/Token.js
create mode 100644 frontend/pages/api/auth/VerifySignupInvite.js
create mode 100644 frontend/pages/api/auth/publicKeyInfisical.js
create mode 100644 frontend/pages/api/files/GetSecrets.js
create mode 100644 frontend/pages/api/files/UploadSecrets.js
create mode 100644 frontend/pages/api/integrations/ChangeHerokuConfigVars.js
create mode 100644 frontend/pages/api/integrations/DeleteIntegration.js
create mode 100644 frontend/pages/api/integrations/DeleteIntegrationAuth.js
create mode 100644 frontend/pages/api/integrations/GetIntegrationApps.js
create mode 100644 frontend/pages/api/integrations/GetIntegrations.js
create mode 100644 frontend/pages/api/integrations/StartIntegration.js
create mode 100644 frontend/pages/api/integrations/authorizeIntegration.js
create mode 100644 frontend/pages/api/integrations/getWorkspaceAuthorizations.js
create mode 100644 frontend/pages/api/integrations/getWorkspaceIntegrations.js
create mode 100644 frontend/pages/api/organization/GetOrg.js
create mode 100644 frontend/pages/api/organization/GetOrgProjects.js
create mode 100644 frontend/pages/api/organization/GetOrgSubscription.js
create mode 100644 frontend/pages/api/organization/GetOrgUserProjects.js
create mode 100644 frontend/pages/api/organization/GetOrgUsers.js
create mode 100644 frontend/pages/api/organization/StripeRedirect.js
create mode 100644 frontend/pages/api/organization/addIncidentContact.js
create mode 100644 frontend/pages/api/organization/addUserToOrg.js
create mode 100644 frontend/pages/api/organization/deleteIncidentContact.js
create mode 100644 frontend/pages/api/organization/deleteUserFromOrganization.js
create mode 100644 frontend/pages/api/organization/getIncidentContacts.js
create mode 100644 frontend/pages/api/organization/getOrgs.js
create mode 100644 frontend/pages/api/organization/renameOrg.js
create mode 100644 frontend/pages/api/serviceToken/addServiceToken.js
create mode 100644 frontend/pages/api/serviceToken/getServiceTokens.js
create mode 100644 frontend/pages/api/user/getUser.js
create mode 100644 frontend/pages/api/userActions/checkUserAction.js
create mode 100644 frontend/pages/api/userActions/registerUserAction.js
create mode 100644 frontend/pages/api/workspace/addUserToWorkspace.js
create mode 100644 frontend/pages/api/workspace/changeUserRoleInWorkspace.js
create mode 100644 frontend/pages/api/workspace/createWorkspace.js
create mode 100644 frontend/pages/api/workspace/deleteUserFromWorkspace.js
create mode 100644 frontend/pages/api/workspace/deleteWorkspace.js
create mode 100644 frontend/pages/api/workspace/getLatestFileKey.js
create mode 100644 frontend/pages/api/workspace/getWorkspaceInfo.js
create mode 100644 frontend/pages/api/workspace/getWorkspaceKeys.js
create mode 100644 frontend/pages/api/workspace/getWorkspaceUsers.js
create mode 100644 frontend/pages/api/workspace/getWorkspaces.js
create mode 100644 frontend/pages/api/workspace/renameWorkspace.js
create mode 100644 frontend/pages/api/workspace/uploadKeys.js
create mode 100644 frontend/pages/dashboard.js
create mode 100644 frontend/pages/dashboard/[id].js
create mode 100644 frontend/pages/heroku.js
create mode 100644 frontend/pages/index.js
create mode 100644 frontend/pages/integrations/[id].js
create mode 100644 frontend/pages/login.js
create mode 100644 frontend/pages/noprojects.js
create mode 100644 frontend/pages/requestnewinvite.js
create mode 100644 frontend/pages/settings/billing/[id].js
create mode 100644 frontend/pages/settings/org/[id].js
create mode 100644 frontend/pages/settings/personal/[id].js
create mode 100644 frontend/pages/settings/project/[id].js
create mode 100644 frontend/pages/signup.js
create mode 100644 frontend/pages/signupinvite.js
create mode 100644 frontend/pages/users/[id].js
create mode 100644 frontend/postcss.config.js
create mode 100644 frontend/public/images/biglogo.png
create mode 100644 frontend/public/images/blog1.png
create mode 100644 frontend/public/images/blog3.png
create mode 100644 frontend/public/images/envelope.svg
create mode 100644 frontend/public/images/integrations/Amazon Web Services.png
create mode 100644 frontend/public/images/integrations/Circle CI.png
create mode 100644 frontend/public/images/integrations/Digital Ocean.png
create mode 100644 frontend/public/images/integrations/Google Cloud Platform.png
create mode 100644 frontend/public/images/integrations/Heroku.png
create mode 100644 frontend/public/images/integrations/Microsoft Azure.png
create mode 100644 frontend/public/images/integrations/Netlify.png
create mode 100644 frontend/public/images/integrations/Travis CI.png
create mode 100644 frontend/public/images/loading/loading.gif
create mode 100644 frontend/public/images/loading/loadingblack.gif
create mode 100644 frontend/public/images/logotransparent.png
create mode 100644 frontend/public/infisical.ico
create mode 100644 frontend/public/vercel.svg
create mode 100644 frontend/styles/globals.css
create mode 100644 frontend/tailwind.config.js
create mode 100644 frontend/yarn.lock
create mode 100644 nginx/default.conf
diff --git a/.env.example b/.env.example
new file mode 100644
index 00000000..3693ea6c
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,70 @@
+# Keys
+# Required keys for platform encryption/decryption ops
+PRIVATE_KEY=replace_with_nacl_sk
+PUBLIC_KEY=replace_with_nacl_pk
+ENCRYPTION_KEY=replace_with_lengthy_secure_hex
+
+# JWT
+# Required secrets to sign JWT tokens
+JWT_SIGNUP_SECRET=replace_with_lengthy_secure_hex
+JWT_REFRESH_SECRET=replace_with_lengthy_secure_hex
+JWT_AUTH_SECRET=replace_with_lengthy_secure_hex
+
+# JWT lifetime
+# Optional lifetimes for JWT tokens expressed in seconds or a string
+# describing a time span (e.g. 60, "2 days", "10h", "7d")
+JWT_AUTH_LIFETIME=
+JWT_REFRESH_LIFETIME=
+JWT_SERVICE_SECRET=
+JWT_SIGNUP_LIFETIME=
+
+# Optional lifetimes for OTP expressed in seconds
+EMAIL_TOKEN_LIFETIME=
+
+# MongoDB
+# Backend will connect to the MongoDB instance at connection string MONGO_URL which can either be a ref
+# to the MongoDB container instance or Mongo Cloud
+# Required
+MONGO_URL=mongodb://root:example@mongo:27017/?authSource=admin
+
+# Optional credentials for MongoDB container instance
+MONGO_USERNAME=root
+MONGO_PASSWORD=example
+
+# Mongo-Express vars (needed for development only)
+ME_CONFIG_MONGODB_ADMINUSERNAME=root
+ME_CONFIG_MONGODB_ADMINPASSWORD=example
+ME_CONFIG_MONGODB_URL=mongodb://root:example@mongo:27017/
+
+# Website URL
+# Required
+NODE_ENV=development
+NEXT_PUBLIC_WEBSITE_URL=http://localhost:8080
+
+# Mail/SMTP
+# Required to send emails
+# By default, SMTP_HOST is set to smtp.gmail.com
+SMTP_HOST=smtp.gmail.com
+SMTP_NAME=Team
+SMTP_USERNAME=team@infisical.com
+SMTP_PASSWORD=
+
+# Integration
+# Optional only if integration is used
+OAUTH_CLIENT_SECRET_HEROKU=
+OAUTH_TOKEN_URL_HEROKU=
+
+# Sentry (optional) for monitoring errors
+SENTRY_DSN=
+
+# Infisical Cloud-specific configs
+# Ignore - Not applicable for self-hosted version
+POSTHOG_HOST=
+POSTHOG_PROJECT_API_KEY=
+STRIPE_SECRET_KEY=
+STRIPE_PUBLISHABLE_KEY=
+STRIPE_WEBHOOK_SECRET=
+STRIPE_PRODUCT_CARD_AUTH=
+STRIPE_PRODUCT_PRO=
+STRIPE_PRODUCT_STARTER=
+NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
\ No newline at end of file
diff --git a/.github/workflows/release_build.yml b/.github/workflows/release_build.yml
new file mode 100644
index 00000000..134f1bdc
--- /dev/null
+++ b/.github/workflows/release_build.yml
@@ -0,0 +1,40 @@
+name: goreleaser
+
+on:
+ push:
+ # run only against tags
+ tags:
+ - 'v*'
+
+permissions:
+ contents: write
+ # packages: write
+ # issues: write
+
+jobs:
+ goreleaser:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - run: git fetch --force --tags
+ - uses: actions/setup-go@v3
+ with:
+ go-version: '>=1.19.3'
+ cache: true
+ cache-dependency-path: cli/go.sum
+ # More assembly might be required: Docker logins, GPG, etc. It all depends
+ # on your needs.
+ - uses: goreleaser/goreleaser-action@v2
+ with:
+ # either 'goreleaser' (default) or 'goreleaser-pro':
+ distribution: goreleaser
+ version: latest
+ args: release --rm-dist
+ env:
+ GITHUB_TOKEN: ${{ secrets.GO_RELEASER_GITHUB_TOKEN }}
+ FURY_TOKEN: ${{ secrets.FURYPUSHTOKEN }}
+ # Your GoReleaser Pro key, if you are using the 'goreleaser-pro'
+ # distribution:
+ # GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
diff --git a/.gitignore b/.gitignore
index bbdd0ab6..10c764fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,51 @@
+# backend
node_modules
.env
+.env.dev
+.env.prod
.env.infisical
-.DS_STORE
*~
-*.swn
*.swp
*.swo
+
+.DS_Store
+
+/dist
+
+# frontend
+
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+.env
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+.vercel
+.env.infisical
diff --git a/.goreleaser.yaml b/.goreleaser.yaml
new file mode 100644
index 00000000..636c215c
--- /dev/null
+++ b/.goreleaser.yaml
@@ -0,0 +1,107 @@
+# This is an example .goreleaser.yml file with some sensible defaults.
+# Make sure to check the documentation at https://goreleaser.com
+# before:
+# hooks:
+# # You may remove this if you don't use go modules.
+# - cd cli && go mod tidy
+# # you may remove this if you don't need go generate
+# - cd cli && go generate ./...
+builds:
+ - env:
+ - CGO_ENABLED=0
+ binary: infisical
+ goos:
+ - windows
+ - darwin
+ - linux
+ id: infisical
+ goarch:
+ - arm
+ - amd64
+ - arm64
+ goarm:
+ - 5
+ - 6
+ - 7
+ dir: ./cli
+
+release:
+ replace_existing_draft: true
+ mode: 'replace'
+
+checksum:
+ name_template: 'checksums.txt'
+snapshot:
+ name_template: "{{ incpatch .Version }}"
+changelog:
+ sort: asc
+ filters:
+ exclude:
+ - '^docs:'
+ - '^test:'
+publishers:
+ - name: fury.io
+ ids:
+ - infisical
+ dir: "{{ dir .ArtifactPath }}"
+ cmd: curl -F package=@{{ .ArtifactName }} https://{{ .Env.FURY_TOKEN }}@push.fury.io/infisical/
+
+# publishers:
+# - name: fury.io
+# ids:
+# - infisical
+# dir: "{{ dir .ArtifactPath }}"
+# cmd: curl -F package=@{{ .ArtifactName }} https://{{ .Env.FURY_TOKEN }}@push.fury.io/infisical/
+brews:
+ - name: infisical
+ tap:
+ owner: Infisical
+ name: homebrew-get-cli
+ commit_author:
+ name: "Infisical"
+ email: ai@infisical.com
+ folder: Formula
+ homepage: "https://infisical.com"
+ description: "The official Infisical CLI"
+nfpms:
+- id: infisical
+ file_name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
+ package_name: infisical
+ builds:
+ - infisical
+ vendor: Infisical, Inc
+ homepage: https://infisical.com/
+ maintainer: Infisical, Inc
+ description: The offical Infisical CLI
+ license: Apache 2.0
+ formats:
+ - rpm
+ - deb
+ - apk
+ bindir: /usr/bin
+scoop:
+ bucket:
+ owner: Infisical
+ name: scoop-infisical
+ commit_author:
+ name: "Infisical"
+ email: ai@infisical.com
+ homepage: "https://infisical.com"
+ description: "The official Infisical CLI"
+ license: Apache-2.0
+# dockers:
+# - dockerfile: goreleaser.dockerfile
+# goos: linux
+# goarch: amd64
+# ids:
+# - infisical
+# image_templates:
+# - "infisical/cli:{{ .Version }}"
+# - "infisical/cli:{{ .Major }}.{{ .Minor }}"
+# - "infisical/cli:{{ .Major }}"
+# - "infisical/cli:latest"
+# build_flag_templates:
+# - "--label=org.label-schema.schema-version=1.0"
+# - "--label=org.label-schema.version={{.Version}}"
+# - "--label=org.label-schema.name={{.ProjectName}}"
+# - "--platform=linux/amd64"
\ No newline at end of file
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..4495f9ce
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+team@infisical.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..1bc84223
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,5 @@
+# Contributing to Infisical
+
+Thanks for taking the time to contribute!
+
+Please refer to our Contributing Guide for instructions on how to contribute.
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..f538a83b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+build:
+ docker-compose -f docker-compose.yml -f docker-compose.prod.yml build
+
+push:
+ docker-compose -f docker-compose.yml -f docker-compose.prod.yml push
+
+up-dev:
+ docker-compose -f docker-compose.yml -f docker-compose.dev.yml up --build
+
+up-prod:
+ docker-compose -f docker-compose.yml -f docker-compose.prod.yml up --build
+
+down:
+ docker-compose down
\ No newline at end of file
diff --git a/README.md b/README.md
index 788af42d..f45dbc7c 100644
--- a/README.md
+++ b/README.md
@@ -1,93 +1,70 @@
-
-
+
Infisical
+ Simple, open-source, E2EE platform to sync environment variables
----
+
-# Infisical
+[Infisical](https://infisical.com) is a simple, open source platform to help organizations manage and sync environment variables across their development workflow and infrastructure. It's designed to be simple and end-to-end encrypted.
-[Infisical](https://infisical.com/) is a simple, end-to-end encrypted (E2EE) platform that enables dev teams to sync and manage their environment variables.
+- **User-Friendly Dashboard** to manage your organization's environment variables within projects.
+- **Language-Agnostic** CLI that pulls and injects environment variables into your local workflow.
+- **Authentication/Authorization** for projects (read/write controls coming soon).
+- **Multiple Environments** per project (e.g. development, staging, production, etc.)
+- **Personal/Shared** scoping for environment variables.
+- **1-Click Deploy** to Digital Ocean (other providers coming soon).
+- **Integrations** with CI/CD and production infrastructure (coming soon).
+- **Automatic Secret Rotation** (coming soon).
+- **2FA** (coming soon).
+- **Access Logs** (coming soon).
+- **Slack Integration** (coming soon).
-Infisical enables dev teams to pull and inject environment variables directly from the platform into their local processes just by modifying their start/dev scripts.
+And more.
-It also supports git-like pull/push commands to sync and share .env files manually via CLI if needed.
+## What's cool about this?
-![alt text](/img/infisical_github_repo.png)
+XX
-## Usage
+## Documentation
-For a quick tutorial, check out our getting started video [here](https://www.youtube.com/watch?v=fgNTyZdHiQQ).
+For full documentation, visit [infisical.com/docs](https://infisical.com/docs).
-Head over to [Infisical](https://infisical.com/) to make an account and create a project for your app. Once you've made an account, populate the project with your environment variables and invite your team.
+To see how to contribute, visit [Getting Started](./DEVELOPERS.md).
-Once you’ve done that, return here to pull and inject secrets from the project to your local process/project.
+## Integrations
-### Step 1: Modify your dev script
+We're currently setting the foundation and building integrations so secrets can be synced everywhere.
-Infisical works with leading JS tools and frameworks to pull and inject secrets into your local environment during development. This includes Express, Fastify, Koa (+/- nodemon) as well as Create-React-App, Next.js, NestJS, and Gatsby.
+- [x] Docker
+- [x] Docker Compose
+- [x] Heroku
+- [ ] Vercel
+- [ ] Kubernetes
+- [ ] AWS
+- [ ] GCP
+- [ ] Azure
+- [ ] Digital Ocean
+- [ ] GitLab
+- [ ] CircleCI
-Navigate to your root project folder; feel free to delete your local .env file as it won’t be needed anymore. Now, prepend the Infisical command before whatever dev command you're using in your package.json dev script. This should take the following form where the environment argument is the environment (options are dev, staging, and prod) that you wish to pull from:
+## Community & Support
-```jsx
-"scripts": {
- ...
- "dev": "npx infisical [environment] [start/dev command]"
-}
-```
+- [Community Forum]() for help with building and discussion.
+- [GitHub Issues](https://github.com/Infisical/infisical-cli/issues) for any bugs and errors you encounter using Infisical.
+- [Slack](https://infisical.slack.com/ssb/redirect) for hanging out with the community and quick communication with the team.
-Examples:
+## Status
-**Express, Fastify, Koa (+ nodemon)**
+- [x] Public Alpha: Anyone can sign up over at [infisical.com](https://infisical.com) but go easy on us, there are kinks and we're just getting started.
+- [ ] Public Beta: Stable enough for most non-enterprise use-cases.
+- [ ] Public: Production-ready.
-```jsx
-"scripts": {
- ...
- "dev": "npx infisical dev nodemon index.js"
-}
-```
+We're currently in Public Alpha.
-**Next.js**
+## Open-source vs. paid
-```jsx
-"scripts": {
- ...
- "dev": "npx infisical dev next dev"
-}
-```
+This repo is entirely MIT licensed, with the exception of the `ee` directory which will contain premium enterprise features requring a Infisical license in the future. We're currently focused on developing non-enterprise offerings first that should suit most use-cases.
-**NestJS**
+## Security
-```jsx
-"scripts": {
- ...
- "start:dev": "npx infisical dev nest start --watch"
-}
-```
-
-**Gatsby**
-
-```jsx
-"scripts": {
- ...
- "dev": "npx infisical dev gatsby develop"
-}
-```
-
-### Step 2: Run your dev process
-
-Next, start your dev process. If it’s your first time, then follow the prompt to log in and connect to the project:
-
-```
-npm run dev
-```
-
-Voila, you’re now automatically pulling and injecting secrets into your local environment every time you run your dev script!
-
-Feel free to check out the full usage documentation and list of commands [here](https://infisical.com/docs/gettingStarted).
-
-## How it Works
-
-Infisical uses end-to-end encryption to securely store and share secrets. It uses secure remote password (SRP) to handle authentication and public-key cryptography for secret sharing and syncing; your secrets are symmetrically encrypted at rest by keys decryptable-only by intended parties in your team. Put simply, we've put measures in place so that secrets remain your-eyes-only - all while making minimal user-experience trade-offs.
-
-For a fuller discussion on how it works, head to: [Infisical](https://infisical.com)
+Looking to report a security vulnerability? Please refer to our [SECURITY.md](./SECURITY.md) file.
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 00000000..bc383f10
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,9 @@
+# Security Policy
+
+## Supported Versions
+
+We always recommend using the latest version of Infisical to ensure you get all security updates.
+
+## Reporting a Vulnerability
+
+Please report security vulnerabilities or concerns to team@infisical.com.
diff --git a/backend/.dockerignore b/backend/.dockerignore
new file mode 100644
index 00000000..b484ea02
--- /dev/null
+++ b/backend/.dockerignore
@@ -0,0 +1,11 @@
+node_modules
+.env
+.env.*
+.git
+.gitignore
+Dockerfile
+.dockerignore
+docker-compose.*
+.DS_Store
+*.swp
+*~
diff --git a/backend/.eslintignore b/backend/.eslintignore
new file mode 100644
index 00000000..76d195ba
--- /dev/null
+++ b/backend/.eslintignore
@@ -0,0 +1,2 @@
+node_modules
+built
\ No newline at end of file
diff --git a/backend/.eslintrc b/backend/.eslintrc
new file mode 100644
index 00000000..a0c373ec
--- /dev/null
+++ b/backend/.eslintrc
@@ -0,0 +1,18 @@
+{
+ "root": true,
+ "parser": "@typescript-eslint/parser",
+ "plugins": [
+ "@typescript-eslint",
+ "prettier"
+ ],
+ "extends": [
+ "eslint:recommended",
+ "plugin:@typescript-eslint/eslint-recommended",
+ "plugin:@typescript-eslint/recommended",
+ "prettier"
+ ],
+ "rules": {
+ "no-console": 2,
+ "prettier/prettier": 2
+ }
+}
\ No newline at end of file
diff --git a/backend/.prettierrc b/backend/.prettierrc
new file mode 100644
index 00000000..a5a98113
--- /dev/null
+++ b/backend/.prettierrc
@@ -0,0 +1,7 @@
+{
+ "semi": true,
+ "trailingComma": "none",
+ "singleQuote": true,
+ "printWidth": 80,
+ "useTabs": true
+ }
diff --git a/backend/Dockerfile b/backend/Dockerfile
new file mode 100644
index 00000000..2cc27094
--- /dev/null
+++ b/backend/Dockerfile
@@ -0,0 +1,12 @@
+FROM node:16-bullseye-slim
+
+WORKDIR /app
+
+COPY package*.json .
+
+RUN npm install
+
+COPY . .
+
+CMD ["npm", "run", "start"]
+
diff --git a/backend/environment.d.ts b/backend/environment.d.ts
new file mode 100644
index 00000000..52f27643
--- /dev/null
+++ b/backend/environment.d.ts
@@ -0,0 +1,37 @@
+export {};
+
+declare global {
+ namespace NodeJS {
+ interface ProcessEnv {
+ EMAIL_TOKEN_LIFETIME: string;
+ ENCRYPTION_KEY: string;
+ JWT_AUTH_LIFETIME: string;
+ JWT_AUTH_SECRET: string;
+ JWT_REFRESH_LIFETIME: string;
+ JWT_REFRESH_SECRET: string;
+ JWT_SERVICE_SECRET: string;
+ JWT_SIGNUP_LIFETIME: string;
+ JWT_SIGNUP_SECRET: string;
+ MONGO_URL: string;
+ NODE_ENV: 'development' | 'staging' | 'testing' | 'production';
+ OAUTH_CLIENT_SECRET_HEROKU: string;
+ OAUTH_TOKEN_URL_HEROKU: string;
+ POSTHOG_HOST: string;
+ POSTHOG_PROJECT_API_KEY: string;
+ PRIVATE_KEY: string;
+ PUBLIC_KEY: string;
+ SENTRY_DSN: string;
+ SMTP_HOST: string;
+ SMTP_NAME: string;
+ SMTP_PASSWORD: string;
+ SMTP_USERNAME: string;
+ STRIPE_PRODUCT_CARD_AUTH: string;
+ STRIPE_PRODUCT_PRO: string;
+ STRIPE_PRODUCT_STARTER: string;
+ STRIPE_PUBLISHABLE_KEY: string;
+ STRIPE_SECRET_KEY: string;
+ STRIPE_WEBHOOK_SECRET: string;
+ WEBSITE_URL: string;
+ }
+ }
+}
diff --git a/backend/img/dashboard.png b/backend/img/dashboard.png
new file mode 100644
index 0000000000000000000000000000000000000000..75791f4e9a76419f4f346552b1069950935c1e55
GIT binary patch
literal 504493
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
L(@GewC4
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