diff --git a/.github/workflows/close_inactive_issues.yml b/.github/workflows/close_inactive_issues.yml
new file mode 100644
index 000000000..315c9e929
--- /dev/null
+++ b/.github/workflows/close_inactive_issues.yml
@@ -0,0 +1,22 @@
+name: Close inactive issues
+on:
+ schedule:
+ - cron: "30 1 * * *"
+
+jobs:
+ close-issues:
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ pull-requests: write
+ steps:
+ - uses: actions/stale@v4
+ with:
+ days-before-issue-stale: 30
+ days-before-issue-close: 14
+ stale-issue-label: "stale"
+ stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
+ close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
+ days-before-pr-stale: -1
+ days-before-pr-close: -1
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/README.md b/README.md
index 0b5848f5a..169d51509 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
Slack |
Infisical Cloud |
Self-Hosting |
- Docs |
+ Docs |
Website
@@ -31,11 +31,11 @@
**[Infisical](https://infisical.com)** is an open source, E2EE tool to help teams manage and sync environment variables across their development workflow and infrastructure. It's designed to be simple and take minutes to get going.
- **User-Friendly Dashboard** to manage your team's environment variables within projects
-- **[Language-Agnostic CLI](https://infisical.com/docs/CLI)** that pulls and injects environment variables into your local workflow
-- **[Complete control over your data](https://infisical.com/docs/self_host_overview)** - host it yourself on any infrastructure
+- **[Language-Agnostic CLI](https://infisical.com/docs/cli/overview)** that pulls and injects environment variables into your local workflow
+- **[Complete control over your data](https://infisical.com/docs/self-hosting/overview)** - host it yourself on any infrastructure
- **Navigate Multiple Environments** per project (e.g. development, staging, production, etc.)
- **Personal/Shared** scoping for environment variables
-- **[Integrations](https://infisical.com/docs/Heroku)** with CI/CD and production infrastructure (Heroku available, more coming soon)
+- **[Integrations](https://infisical.com/docs/integrations/heroku)** with CI/CD and production infrastructure (Heroku available, more coming soon)
- 🔜 **1-Click Deploy** to Digital Ocean and Heroku
- 🔜 **Authentication/Authorization** for projects (read/write controls soon)
- 🔜 **Automatic Secret Rotation**
@@ -49,12 +49,6 @@ And more.
To quickly get started, visit our [get started guide](https://infisical.com/docs/getting-started/introduction).
-## Stay Up-to-Date
-
-Infisical officially launched as v.1.0 on November 21st, 2022. However, a lot of new features are coming very quickly. Watch **releases** of this repository to be notified about future updates:
-
-
-
## What's cool about this?
Infisical is simple, E2EE, and (soon to be) complete.
@@ -65,12 +59,10 @@ We're on a mission to make secret management more accessible to everyone — tha
If you care about efficiency and security, then Infisical is right for you.
-Need any integrations or want a new feature? Feel free to [create an issue](https://github.com/Infisical/infisical/issues) or [contribute](https://infisical.com/docs/contributing) directly to the repository.
+Need any integrations or want a new feature? Feel free to [create an issue](https://github.com/Infisical/infisical/issues) or [contribute](https://infisical.com/docs/contributing/overview) directly to the repository.
## Contributing
-For full documentation, visit [infisical.com/docs](https://infisical.com/docs).
-
Whether it's big or small, we love contributions ❤️ Check out our guide to see how to [get started](https://infisical.com/docs/contributing/overview).
Not sure where to get started? [Book a free, non-pressure pairing sessions with one of our teammates](mailto:tony@infisical.com?subject=Pairing%20session&body=I'd%20like%20to%20do%20a%20pairing%20session!)!
@@ -79,7 +71,7 @@ Not sure where to get started? [Book a free, non-pressure pairing sessions with
- [GitHub Discussions](https://github.com/Infisical/infisical/discussions) for help with building and discussion.
- [GitHub Issues](https://github.com/Infisical/infisical-cli/issues) for any bugs and errors you encounter using Infisical.
-- [Community Slack](https://join.slack.com/t/infisical/shared_invite/zt-1dgg63ln8-G7PCNJdCymAT9YF3j1ewVA) for hanging out with the community and quick communication with the team.
+- [Community Slack](https://join.slack.com/t/infisical-users/shared_invite/zt-1kdbk07ro-RtoyEt_9E~fyzGo_xQYP6g) for hanging out with the community and quick communication with the team.
## Status
@@ -89,13 +81,19 @@ Not sure where to get started? [Book a free, non-pressure pairing sessions with
We're currently in Public Alpha.
+## Stay Up-to-Date
+
+Infisical officially launched as v.1.0 on November 21st, 2022. However, a lot of new features are coming very quickly. Watch **releases** of this repository to be notified about future updates:
+
+
+
## Integrations
We're currently setting the foundation and building integrations so secrets can be synced everywhere. Any help is welcome! :)
-- [x] Docker
-- [x] Docker Compose
-- [x] Heroku
+- [x] [Docker](https://infisical.com/docs/integrations/docker)
+- [x] [Docker Compose](https://infisical.com/docs/integrations/docker-compose)
+- [x] [Heroku](https://infisical.com/docs/integrations/heroku)
- [ ] Vercel
- [ ] Kubernetes
- [ ] AWS
@@ -121,4 +119,4 @@ Looking to report a security vulnerability? Please don't post about it in GitHub
-
+
diff --git a/backend/package-lock.json b/backend/package-lock.json
index 20b1d1f31..63a3a3060 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -31,6 +31,8 @@
"query-string": "^7.1.1",
"rimraf": "^3.0.2",
"stripe": "^10.7.0",
+ "swagger-jsdoc": "^6.2.5",
+ "swagger-ui-express": "^4.6.0",
"tweetnacl": "^1.0.3",
"tweetnacl-util": "^0.15.1",
"typescript": "^4.8.4"
@@ -43,6 +45,8 @@
"@types/jsonwebtoken": "^8.5.9",
"@types/node": "^18.11.3",
"@types/nodemailer": "^6.4.6",
+ "@types/swagger-jsdoc": "^6.0.1",
+ "@types/swagger-ui-express": "^4.1.3",
"@typescript-eslint/eslint-plugin": "^5.40.1",
"@typescript-eslint/parser": "^5.40.1",
"eslint": "^8.26.0",
@@ -70,6 +74,46 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@apidevtools/json-schema-ref-parser": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.0.tgz",
+ "integrity": "sha512-teB30tFooE3iQs2HQIKJ02D8UZA1Xy1zaczzhUjJs0CymYxeC0g+y5rCY2p8NHBM6DBUVoR8rSM4kHLj1WE9mQ==",
+ "dependencies": {
+ "@jsdevtools/ono": "^7.1.3",
+ "@types/json-schema": "^7.0.6",
+ "call-me-maybe": "^1.0.1",
+ "js-yaml": "^4.1.0"
+ }
+ },
+ "node_modules/@apidevtools/openapi-schemas": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz",
+ "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@apidevtools/swagger-methods": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz",
+ "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg=="
+ },
+ "node_modules/@apidevtools/swagger-parser": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.2.tgz",
+ "integrity": "sha512-JFxcEyp8RlNHgBCE98nwuTkZT6eNFPc1aosWV6wPcQph72TSEEu1k3baJD4/x1qznU+JiDdz8F5pTwabZh+Dhg==",
+ "dependencies": {
+ "@apidevtools/json-schema-ref-parser": "^9.0.6",
+ "@apidevtools/openapi-schemas": "^2.0.4",
+ "@apidevtools/swagger-methods": "^3.0.2",
+ "@jsdevtools/ono": "^7.1.3",
+ "call-me-maybe": "^1.0.1",
+ "z-schema": "^4.2.3"
+ },
+ "peerDependencies": {
+ "openapi-types": ">=7"
+ }
+ },
"node_modules/@aws-crypto/ie11-detection": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-2.0.2.tgz",
@@ -2532,6 +2576,11 @@
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
+ "node_modules/@jsdevtools/ono": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
+ "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="
+ },
"node_modules/@juanelas/base64": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@juanelas/base64/-/base64-1.0.5.tgz",
@@ -2843,8 +2892,7 @@
"node_modules/@types/json-schema": {
"version": "7.0.11",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
- "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
- "dev": true
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
},
"node_modules/@types/jsonwebtoken": {
"version": "8.5.9",
@@ -2915,6 +2963,22 @@
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
"dev": true
},
+ "node_modules/@types/swagger-jsdoc": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@types/swagger-jsdoc/-/swagger-jsdoc-6.0.1.tgz",
+ "integrity": "sha512-+MUpcbyxD528dECUBCEVm6abNuORdbuGjbrUdHDeAQ+rkPuo2a+L4N02WJHF3bonSSE6SJ3dUJwF2V6+cHnf0w==",
+ "dev": true
+ },
+ "node_modules/@types/swagger-ui-express": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/@types/swagger-ui-express/-/swagger-ui-express-4.1.3.tgz",
+ "integrity": "sha512-jqCjGU/tGEaqIplPy3WyQg+Nrp6y80DCFnDEAvVKWkJyv0VivSSDCChkppHRHAablvInZe6pijDFMnavtN0vqA==",
+ "dev": true,
+ "dependencies": {
+ "@types/express": "*",
+ "@types/serve-static": "*"
+ }
+ },
"node_modules/@types/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
@@ -3279,8 +3343,7 @@
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/array-flatten": {
"version": "1.1.1",
@@ -3617,6 +3680,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/call-me-maybe": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
+ "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ=="
+ },
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -3816,6 +3884,14 @@
"node": ">= 0.8"
}
},
+ "node_modules/commander": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz",
+ "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -4055,7 +4131,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
- "dev": true,
"dependencies": {
"esutils": "^2.0.2"
},
@@ -4396,7 +4471,6 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -5954,7 +6028,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
"dependencies": {
"argparse": "^2.0.1"
},
@@ -6150,6 +6223,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+ },
"node_modules/lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
@@ -6160,6 +6238,11 @@
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
},
+ "node_modules/lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+ },
"node_modules/lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
@@ -6186,6 +6269,11 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
+ "node_modules/lodash.mergewith": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
+ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="
+ },
"node_modules/lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
@@ -9247,6 +9335,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/openapi-types": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.0.2.tgz",
+ "integrity": "sha512-GuTo7FyZjOIWVhIhQSWJVaws6A82sWIGyQogxxYBYKZ0NBdyP2CYSIgOwFfSB+UVoPExk/YzFpyYitHS8KVZtA==",
+ "peer": true
+ },
"node_modules/optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
@@ -10284,6 +10378,74 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/swagger-jsdoc": {
+ "version": "6.2.5",
+ "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.5.tgz",
+ "integrity": "sha512-l+cdsKS2y+QDhrH1TJSUiE0y9XKuf5xaGSatjf0hR/wjTlMpO8WfubBK9d/nASdbHPMtj9iJZLBH2ogBEhL7Sw==",
+ "dependencies": {
+ "commander": "6.2.0",
+ "doctrine": "3.0.0",
+ "glob": "7.1.6",
+ "lodash.mergewith": "^4.6.2",
+ "swagger-parser": "10.0.2",
+ "yaml": "2.0.0-1"
+ },
+ "bin": {
+ "swagger-jsdoc": "bin/swagger-jsdoc.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/swagger-jsdoc/node_modules/glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/swagger-parser": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.2.tgz",
+ "integrity": "sha512-9jHkHM+QXyLGFLk1DkXBwV+4HyNm0Za3b8/zk/+mjr8jgOSiqm3FOTHBSDsBjtn9scdL+8eWcHdupp2NLM8tDw==",
+ "dependencies": {
+ "@apidevtools/swagger-parser": "10.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/swagger-ui-dist": {
+ "version": "4.15.5",
+ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.15.5.tgz",
+ "integrity": "sha512-V3eIa28lwB6gg7/wfNvAbjwJYmDXy1Jo1POjyTzlB6wPcHiGlRxq39TSjYGVjQrUSAzpv+a7nzp7mDxgNy57xA=="
+ },
+ "node_modules/swagger-ui-express": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.6.0.tgz",
+ "integrity": "sha512-ZxpQFp1JR2RF8Ar++CyJzEDdvufa08ujNUJgMVTMWPi86CuQeVdBtvaeO/ysrz6dJAYXf9kbVNhWD7JWocwqsA==",
+ "dependencies": {
+ "swagger-ui-dist": ">=4.11.0"
+ },
+ "engines": {
+ "node": ">= v0.10.32"
+ },
+ "peerDependencies": {
+ "express": ">=4.0.0"
+ }
+ },
"node_modules/test-exclude": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
@@ -10758,6 +10920,14 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
+ "node_modules/yaml": {
+ "version": "2.0.0-1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz",
+ "integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/yargs": {
"version": "17.6.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
@@ -10805,6 +10975,31 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/z-schema": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-4.2.4.tgz",
+ "integrity": "sha512-YvBeW5RGNeNzKOUJs3rTL4+9rpcvHXt5I051FJbOcitV8bl40pEfcG0Q+dWSwS0/BIYrMZ/9HHoqLllMkFhD0w==",
+ "dependencies": {
+ "lodash.get": "^4.4.2",
+ "lodash.isequal": "^4.5.0",
+ "validator": "^13.6.0"
+ },
+ "bin": {
+ "z-schema": "bin/z-schema"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ },
+ "optionalDependencies": {
+ "commander": "^2.7.1"
+ }
+ },
+ "node_modules/z-schema/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "optional": true
}
},
"dependencies": {
@@ -10818,6 +11013,40 @@
"@jridgewell/trace-mapping": "^0.3.9"
}
},
+ "@apidevtools/json-schema-ref-parser": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.0.tgz",
+ "integrity": "sha512-teB30tFooE3iQs2HQIKJ02D8UZA1Xy1zaczzhUjJs0CymYxeC0g+y5rCY2p8NHBM6DBUVoR8rSM4kHLj1WE9mQ==",
+ "requires": {
+ "@jsdevtools/ono": "^7.1.3",
+ "@types/json-schema": "^7.0.6",
+ "call-me-maybe": "^1.0.1",
+ "js-yaml": "^4.1.0"
+ }
+ },
+ "@apidevtools/openapi-schemas": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz",
+ "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ=="
+ },
+ "@apidevtools/swagger-methods": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz",
+ "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg=="
+ },
+ "@apidevtools/swagger-parser": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.2.tgz",
+ "integrity": "sha512-JFxcEyp8RlNHgBCE98nwuTkZT6eNFPc1aosWV6wPcQph72TSEEu1k3baJD4/x1qznU+JiDdz8F5pTwabZh+Dhg==",
+ "requires": {
+ "@apidevtools/json-schema-ref-parser": "^9.0.6",
+ "@apidevtools/openapi-schemas": "^2.0.4",
+ "@apidevtools/swagger-methods": "^3.0.2",
+ "@jsdevtools/ono": "^7.1.3",
+ "call-me-maybe": "^1.0.1",
+ "z-schema": "^4.2.3"
+ }
+ },
"@aws-crypto/ie11-detection": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-2.0.2.tgz",
@@ -12978,6 +13207,11 @@
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
+ "@jsdevtools/ono": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
+ "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="
+ },
"@juanelas/base64": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@juanelas/base64/-/base64-1.0.5.tgz",
@@ -13265,8 +13499,7 @@
"@types/json-schema": {
"version": "7.0.11",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
- "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
- "dev": true
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
},
"@types/jsonwebtoken": {
"version": "8.5.9",
@@ -13337,6 +13570,22 @@
"integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
"dev": true
},
+ "@types/swagger-jsdoc": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@types/swagger-jsdoc/-/swagger-jsdoc-6.0.1.tgz",
+ "integrity": "sha512-+MUpcbyxD528dECUBCEVm6abNuORdbuGjbrUdHDeAQ+rkPuo2a+L4N02WJHF3bonSSE6SJ3dUJwF2V6+cHnf0w==",
+ "dev": true
+ },
+ "@types/swagger-ui-express": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/@types/swagger-ui-express/-/swagger-ui-express-4.1.3.tgz",
+ "integrity": "sha512-jqCjGU/tGEaqIplPy3WyQg+Nrp6y80DCFnDEAvVKWkJyv0VivSSDCChkppHRHAablvInZe6pijDFMnavtN0vqA==",
+ "dev": true,
+ "requires": {
+ "@types/express": "*",
+ "@types/serve-static": "*"
+ }
+ },
"@types/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
@@ -13569,8 +13818,7 @@
"argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"array-flatten": {
"version": "1.1.1",
@@ -13819,6 +14067,11 @@
"get-intrinsic": "^1.0.2"
}
},
+ "call-me-maybe": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
+ "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ=="
+ },
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -13959,6 +14212,11 @@
"delayed-stream": "~1.0.0"
}
},
+ "commander": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz",
+ "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q=="
+ },
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -14140,7 +14398,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
- "dev": true,
"requires": {
"esutils": "^2.0.2"
}
@@ -14386,8 +14643,7 @@
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "dev": true
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
},
"etag": {
"version": "1.8.1",
@@ -15550,7 +15806,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
"requires": {
"argparse": "^2.0.1"
}
@@ -15708,6 +15963,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+ },
"lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
@@ -15718,6 +15978,11 @@
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
},
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+ },
"lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
@@ -15744,6 +16009,11 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
+ "lodash.mergewith": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
+ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="
+ },
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
@@ -17905,6 +18175,12 @@
"mimic-fn": "^2.1.0"
}
},
+ "openapi-types": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.0.2.tgz",
+ "integrity": "sha512-GuTo7FyZjOIWVhIhQSWJVaws6A82sWIGyQogxxYBYKZ0NBdyP2CYSIgOwFfSB+UVoPExk/YzFpyYitHS8KVZtA==",
+ "peer": true
+ },
"optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
@@ -18649,6 +18925,55 @@
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true
},
+ "swagger-jsdoc": {
+ "version": "6.2.5",
+ "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.5.tgz",
+ "integrity": "sha512-l+cdsKS2y+QDhrH1TJSUiE0y9XKuf5xaGSatjf0hR/wjTlMpO8WfubBK9d/nASdbHPMtj9iJZLBH2ogBEhL7Sw==",
+ "requires": {
+ "commander": "6.2.0",
+ "doctrine": "3.0.0",
+ "glob": "7.1.6",
+ "lodash.mergewith": "^4.6.2",
+ "swagger-parser": "10.0.2",
+ "yaml": "2.0.0-1"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ }
+ }
+ },
+ "swagger-parser": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.2.tgz",
+ "integrity": "sha512-9jHkHM+QXyLGFLk1DkXBwV+4HyNm0Za3b8/zk/+mjr8jgOSiqm3FOTHBSDsBjtn9scdL+8eWcHdupp2NLM8tDw==",
+ "requires": {
+ "@apidevtools/swagger-parser": "10.0.2"
+ }
+ },
+ "swagger-ui-dist": {
+ "version": "4.15.5",
+ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.15.5.tgz",
+ "integrity": "sha512-V3eIa28lwB6gg7/wfNvAbjwJYmDXy1Jo1POjyTzlB6wPcHiGlRxq39TSjYGVjQrUSAzpv+a7nzp7mDxgNy57xA=="
+ },
+ "swagger-ui-express": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.6.0.tgz",
+ "integrity": "sha512-ZxpQFp1JR2RF8Ar++CyJzEDdvufa08ujNUJgMVTMWPi86CuQeVdBtvaeO/ysrz6dJAYXf9kbVNhWD7JWocwqsA==",
+ "requires": {
+ "swagger-ui-dist": ">=4.11.0"
+ }
+ },
"test-exclude": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
@@ -18984,6 +19309,11 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
+ "yaml": {
+ "version": "2.0.0-1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz",
+ "integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ=="
+ },
"yargs": {
"version": "17.6.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
@@ -19016,6 +19346,25 @@
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true
+ },
+ "z-schema": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-4.2.4.tgz",
+ "integrity": "sha512-YvBeW5RGNeNzKOUJs3rTL4+9rpcvHXt5I051FJbOcitV8bl40pEfcG0Q+dWSwS0/BIYrMZ/9HHoqLllMkFhD0w==",
+ "requires": {
+ "commander": "^2.7.1",
+ "lodash.get": "^4.4.2",
+ "lodash.isequal": "^4.5.0",
+ "validator": "^13.6.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "optional": true
+ }
+ }
}
}
}
diff --git a/backend/package.json b/backend/package.json
index ce632f3b5..9dfe476e9 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -22,6 +22,8 @@
"query-string": "^7.1.1",
"rimraf": "^3.0.2",
"stripe": "^10.7.0",
+ "swagger-jsdoc": "^6.2.5",
+ "swagger-ui-express": "^4.6.0",
"tweetnacl": "^1.0.3",
"tweetnacl-util": "^0.15.1",
"typescript": "^4.8.4"
@@ -56,6 +58,8 @@
"@types/jsonwebtoken": "^8.5.9",
"@types/node": "^18.11.3",
"@types/nodemailer": "^6.4.6",
+ "@types/swagger-jsdoc": "^6.0.1",
+ "@types/swagger-ui-express": "^4.1.3",
"@typescript-eslint/eslint-plugin": "^5.40.1",
"@typescript-eslint/parser": "^5.40.1",
"eslint": "^8.26.0",
diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts
index 1b2178ca0..fd8f9c55b 100644
--- a/backend/src/config/index.ts
+++ b/backend/src/config/index.ts
@@ -1,5 +1,5 @@
const PORT = process.env.PORT || 4000;
-const EMAIL_TOKEN_LIFETIME = process.env.EMAIL_TOKEN_LIFETIME! || '86400'; // investigate
+const EMAIL_TOKEN_LIFETIME = process.env.EMAIL_TOKEN_LIFETIME! || '86400';
const ENCRYPTION_KEY = process.env.ENCRYPTION_KEY!;
const JWT_AUTH_LIFETIME = process.env.JWT_AUTH_LIFETIME! || '10d';
const JWT_AUTH_SECRET = process.env.JWT_AUTH_SECRET!;
diff --git a/backend/src/controllers/organizationController.ts b/backend/src/controllers/organizationController.ts
index bce757d0a..056990acc 100644
--- a/backend/src/controllers/organizationController.ts
+++ b/backend/src/controllers/organizationController.ts
@@ -8,6 +8,7 @@ import {
STRIPE_PRODUCT_CARD_AUTH
} from '../config';
import Stripe from 'stripe';
+
const stripe = new Stripe(STRIPE_SECRET_KEY, {
apiVersion: '2022-08-01'
});
diff --git a/backend/src/helpers/rateLimiter.ts b/backend/src/helpers/rateLimiter.ts
index eb5112560..a0788246a 100644
--- a/backend/src/helpers/rateLimiter.ts
+++ b/backend/src/helpers/rateLimiter.ts
@@ -3,7 +3,7 @@ import rateLimit from 'express-rate-limit';
// 300 requests per 15 minutes
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
- max: 300,
+ max: 400,
standardHeaders: true,
legacyHeaders: false
});
@@ -11,7 +11,7 @@ const apiLimiter = rateLimit({
// 5 requests per hour
const signupLimiter = rateLimit({
windowMs: 60 * 60 * 1000,
- max: 5,
+ max: 10,
standardHeaders: true,
legacyHeaders: false
});
@@ -19,7 +19,7 @@ const signupLimiter = rateLimit({
// 10 requests per hour
const loginLimiter = rateLimit({
windowMs: 60 * 60 * 1000,
- max: 10,
+ max: 20,
standardHeaders: true,
legacyHeaders: false
});
@@ -27,7 +27,7 @@ const loginLimiter = rateLimit({
// 5 requests per hour
const passwordLimiter = rateLimit({
windowMs: 60 * 60 * 1000,
- max: 5,
+ max: 10,
standardHeaders: true,
legacyHeaders: false
});
diff --git a/backend/src/index.ts b/backend/src/index.ts
index fc1d9a417..1bc596865 100644
--- a/backend/src/index.ts
+++ b/backend/src/index.ts
@@ -4,9 +4,11 @@ import cors from 'cors';
import cookieParser from 'cookie-parser';
import mongoose from 'mongoose';
import dotenv from 'dotenv';
+import swaggerJSDoc from 'swagger-jsdoc';
+import swaggerUi from 'swagger-ui-express';
+
dotenv.config();
import * as Sentry from '@sentry/node';
-// import { PostHogClient } from './services';
import { PORT, SENTRY_DSN, NODE_ENV, MONGO_URL, SITE_URL, POSTHOG_PROJECT_API_KEY, POSTHOG_HOST, TELEMETRY_ENABLED } from './config';
import { apiLimiter } from './helpers/rateLimiter';
@@ -19,12 +21,6 @@ Sentry.init({
environment: NODE_ENV
});
-// PostHogClient.init({
-// projectApiKey: POSTHOG_PROJECT_API_KEY,
-// host: POSTHOG_HOST,
-// telemetryEnabled: TELEMETRY_ENABLED
-// });
-
import {
signup as signupRouter,
auth as authRouter,
@@ -72,6 +68,39 @@ if (NODE_ENV === 'production') {
app.use(helmet());
}
+if (NODE_ENV === 'development') {
+ const swaggerDefinition = {
+ openapi: '3.0.0',
+ info: {
+ title: 'Infisical API',
+ version: '1.0.0',
+ description: 'Infisical is an open-source, E2EE tool to sync environment variables across your team and infrastructure.',
+ license: {
+ name: 'License',
+ url: 'https://github.com/Infisical/infisical/blob/main/LICENSE'
+ },
+ contact: {
+ name: 'Infisical',
+ url: 'https://infisical.com'
+ },
+ },
+ servers: [
+ {
+ url: 'http://localhost:8080/api/v1',
+ description: 'Development server'
+ }
+ ]
+ }
+
+ const options = {
+ swaggerDefinition,
+ apis: ['./src/routes/*.ts']
+ }
+
+ const swaggerSpec = swaggerJSDoc(options);
+ app.use('/api/docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
+}
+
app.use(express.json());
// routers
diff --git a/backend/src/routes/auth.ts b/backend/src/routes/auth.ts
index 43a57fe7e..52cd6ac48 100644
--- a/backend/src/routes/auth.ts
+++ b/backend/src/routes/auth.ts
@@ -11,6 +11,53 @@ router.post(
authController.getNewToken
);
+/**
+ * @swagger
+ * /auth/login1:
+ * post:
+ * summary: Return server's public key and user's salt for login via SRP.
+ * description: As part of the 1st step of secure remote password (SRP), return server's public key and user's salt.
+ * requestBody:
+ * required: true
+ * content:
+ * application/json:
+ * schema:
+ * type: object
+ * properties:
+ * email:
+ * type: string
+ * description: Email of user
+ * example: 'johndoe@gmail.com'
+ * clientPublicKey:
+ * type: string
+ * description: Client-side SRP-generated public key
+ * example: 'b13dc83cb...'
+ * responses:
+ * 200:
+ * description: Object containing the server's public key and user's salt.
+ * content:
+ * application/json:
+ * schema:
+ * type: object
+ * properties:
+ * serverPublicKey:
+ * type: string
+ * description: Server-side SRP-generated public key
+ * example: 'b13dc83cb...'
+ * salt:
+ * type: string
+ * description: User's salt
+ * example: 'dc1ac694f...'
+ * 400:
+ * content:
+ * application/json:
+ * schema:
+ * type: object
+ * properties:
+ * message:
+ * type: string
+ * example: 'Failed to start authentication process'
+ */
router.post(
'/login1',
loginLimiter,
diff --git a/cli/packages/cmd/root.go b/cli/packages/cmd/root.go
index f33cbb249..826ccb4df 100644
--- a/cli/packages/cmd/root.go
+++ b/cli/packages/cmd/root.go
@@ -15,7 +15,7 @@ var rootCmd = &cobra.Command{
Short: "Infisical CLI is used to inject environment variables into any process",
Long: `Infisical is a simple, end-to-end encrypted service that enables teams to sync and manage their environment variables across their development life cycle.`,
CompletionOptions: cobra.CompletionOptions{DisableDefaultCmd: true},
- Version: "0.1.4",
+ Version: "0.1.5",
}
// Execute adds all child commands to the root command and sets flags appropriately.
diff --git a/cli/packages/cmd/run.go b/cli/packages/cmd/run.go
index 1c07f06c8..6b44fa548 100644
--- a/cli/packages/cmd/run.go
+++ b/cli/packages/cmd/run.go
@@ -33,6 +33,13 @@ var runCmd = &cobra.Command{
return
}
+ shouldExpandSecrets, err := cmd.Flags().GetBool("expand")
+ if err != nil {
+ log.Errorln("Unable to parse the substitute flag")
+ log.Debugln(err)
+ return
+ }
+
projectId, err := cmd.Flags().GetString("projectId")
if err != nil {
log.Errorln("Unable to parse the project id flag")
@@ -82,7 +89,13 @@ var runCmd = &cobra.Command{
}
}
- execCmd(args[0], args[1:], envsFromApi)
+ if shouldExpandSecrets {
+ substitutions := util.SubstituteSecrets(envsFromApi)
+ execCmd(args[0], args[1:], substitutions)
+ } else {
+ execCmd(args[0], args[1:], envsFromApi)
+ }
+
},
}
@@ -90,6 +103,7 @@ func init() {
rootCmd.AddCommand(runCmd)
runCmd.Flags().StringP("env", "e", "dev", "Set the environment (dev, prod, etc.) from which your secrets should be pulled from")
runCmd.Flags().String("projectId", "", "The project ID from which your secrets should be pulled from")
+ runCmd.Flags().Bool("expand", true, "Parse shell parameter expansions in your secrets")
}
// Credit: inspired by AWS Valut
diff --git a/cli/packages/models/error.go b/cli/packages/models/error.go
new file mode 100644
index 000000000..28e48d54d
--- /dev/null
+++ b/cli/packages/models/error.go
@@ -0,0 +1,14 @@
+package models
+
+import log "github.com/sirupsen/logrus"
+
+// Custom error type so that we can give helpful messages in CLI
+type Error struct {
+ Err error
+ DebugMessage string
+ FriendlyMessage string
+}
+
+func (e *Error) printFriendlyMessage() {
+ log.Infoln(e.FriendlyMessage)
+}
diff --git a/cli/packages/util/secrets.go b/cli/packages/util/secrets.go
index 475640713..5cf76d48e 100644
--- a/cli/packages/util/secrets.go
+++ b/cli/packages/util/secrets.go
@@ -4,6 +4,7 @@ import (
"encoding/base64"
"errors"
"fmt"
+ "regexp"
"strings"
"github.com/Infisical/infisical-merge/packages/models"
@@ -205,3 +206,73 @@ func GetWorkSpacesFromAPI(userCreds models.UserCredentials) (workspaces []models
return getWorkSpacesResponse.Workspaces, nil
}
+
+func getExpandedEnvVariable(secrets []models.SingleEnvironmentVariable, variableWeAreLookingFor string, hashMapOfCompleteVariables map[string]string, hashMapOfSelfRefs map[string]string) string {
+ if value, found := hashMapOfCompleteVariables[variableWeAreLookingFor]; found {
+ return value
+ }
+
+ for _, secret := range secrets {
+ if secret.Key == variableWeAreLookingFor {
+ regex := regexp.MustCompile(`\${([^\}]*)}`)
+ variablesToPopulate := regex.FindAllString(secret.Value, -1)
+
+ // case: variable is a constant so return its value
+ if len(variablesToPopulate) == 0 {
+ return secret.Value
+ }
+
+ valueToEdit := secret.Value
+ for _, variableWithSign := range variablesToPopulate {
+ variableWithoutSign := strings.Trim(variableWithSign, "}")
+ variableWithoutSign = strings.Trim(variableWithoutSign, "${")
+
+ // case: reference to self
+ if variableWithoutSign == secret.Key {
+ hashMapOfSelfRefs[variableWithoutSign] = variableWithoutSign
+ continue
+ } else {
+ var expandedVariableValue string
+
+ if preComputedVariable, found := hashMapOfCompleteVariables[variableWithoutSign]; found {
+ expandedVariableValue = preComputedVariable
+ } else {
+ expandedVariableValue = getExpandedEnvVariable(secrets, variableWithoutSign, hashMapOfCompleteVariables, hashMapOfSelfRefs)
+ hashMapOfCompleteVariables[variableWithoutSign] = expandedVariableValue
+ }
+
+ // If after expanding all the vars above, is the current var a self ref? if so no replacement needed for it
+ if _, found := hashMapOfSelfRefs[variableWithoutSign]; found {
+ continue
+ } else {
+ valueToEdit = strings.ReplaceAll(valueToEdit, variableWithSign, expandedVariableValue)
+ }
+ }
+ }
+
+ return valueToEdit
+
+ } else {
+ continue
+ }
+ }
+
+ return "${" + variableWeAreLookingFor + "}"
+}
+
+func SubstituteSecrets(secrets []models.SingleEnvironmentVariable) []models.SingleEnvironmentVariable {
+ hashMapOfCompleteVariables := make(map[string]string)
+ hashMapOfSelfRefs := make(map[string]string)
+ expandedSecrets := []models.SingleEnvironmentVariable{}
+
+ for _, secret := range secrets {
+ expandedVariable := getExpandedEnvVariable(secrets, secret.Key, hashMapOfCompleteVariables, hashMapOfSelfRefs)
+ expandedSecrets = append(expandedSecrets, models.SingleEnvironmentVariable{
+ Key: secret.Key,
+ Value: expandedVariable,
+ })
+
+ }
+
+ return expandedSecrets
+}
diff --git a/cli/packages/util/secrets_test.go b/cli/packages/util/secrets_test.go
new file mode 100644
index 000000000..513e4f7e3
--- /dev/null
+++ b/cli/packages/util/secrets_test.go
@@ -0,0 +1,160 @@
+package util
+
+import (
+ "testing"
+
+ "github.com/Infisical/infisical-merge/packages/models"
+)
+
+// References to self should return the value unaltered
+func Test_SubstituteSecrets_When_ReferenceToSelf(t *testing.T) {
+
+ var tests = []struct {
+ Key string
+ Value string
+ ExpectedValue string
+ }{
+ {Key: "A", Value: "${A}", ExpectedValue: "${A}"},
+ {Key: "A", Value: "${A} ${A}", ExpectedValue: "${A} ${A}"},
+ {Key: "A", Value: "${A}${A}", ExpectedValue: "${A}${A}"},
+ }
+
+ for _, test := range tests {
+ secret := models.SingleEnvironmentVariable{
+ Key: test.Key,
+ Value: test.Value,
+ }
+
+ secrets := []models.SingleEnvironmentVariable{secret}
+ result := SubstituteSecrets(secrets)
+
+ if result[0].Value != test.ExpectedValue {
+ t.Errorf("Test_SubstituteSecrets_When_ReferenceToSelf: expected %s but got %s for input %s", test.ExpectedValue, result[0].Value, test.Value)
+ }
+
+ }
+}
+
+func Test_SubstituteSecrets_When_ReferenceDoesNotExist(t *testing.T) {
+
+ var tests = []struct {
+ Key string
+ Value string
+ ExpectedValue string
+ }{
+ {Key: "A", Value: "${X}", ExpectedValue: "${X}"},
+ {Key: "A", Value: "${H}HELLO", ExpectedValue: "${H}HELLO"},
+ {Key: "A", Value: "${L}${S}", ExpectedValue: "${L}${S}"},
+ }
+
+ for _, test := range tests {
+ secret := models.SingleEnvironmentVariable{
+ Key: test.Key,
+ Value: test.Value,
+ }
+
+ secrets := []models.SingleEnvironmentVariable{secret}
+ result := SubstituteSecrets(secrets)
+
+ if result[0].Value != test.ExpectedValue {
+ t.Errorf("Test_SubstituteSecrets_When_ReferenceToSelf: expected %s but got %s for input %s", test.ExpectedValue, result[0].Value, test.Value)
+ }
+
+ }
+}
+
+func Test_SubstituteSecrets_When_ReferenceDoesNotExist_And_Self_Referencing(t *testing.T) {
+
+ tests := []struct {
+ Key string
+ Value string
+ ExpectedValue string
+ }{
+ {
+ Key: "O",
+ Value: "${P} ==$$ ${X} ${UNKNOWN} ${A}",
+ ExpectedValue: "DOMAIN === ${A} DOMAIN >>> ==$$ DOMAIN ${UNKNOWN} ${A}",
+ },
+ {
+ Key: "X",
+ Value: "DOMAIN",
+ ExpectedValue: "DOMAIN",
+ },
+ {
+ Key: "A",
+ Value: "*${A}* ${X}",
+ ExpectedValue: "*${A}* DOMAIN",
+ },
+ {
+ Key: "H",
+ Value: "${X} >>>",
+ ExpectedValue: "DOMAIN >>>",
+ },
+ {
+ Key: "P",
+ Value: "DOMAIN === ${A} ${H}",
+ ExpectedValue: "DOMAIN === ${A} DOMAIN >>>",
+ },
+ {
+ Key: "T",
+ Value: "${P} ==$$ ${X} ${UNKNOWN} ${A} ${P} ==$$ ${X} ${UNKNOWN} ${A}",
+ ExpectedValue: "DOMAIN === ${A} DOMAIN >>> ==$$ DOMAIN ${UNKNOWN} ${A} DOMAIN === ${A} DOMAIN >>> ==$$ DOMAIN ${UNKNOWN} ${A}",
+ },
+ {
+ Key: "S",
+ Value: "${ SSS$$ ${HEY}",
+ ExpectedValue: "${ SSS$$ ${HEY}",
+ },
+ }
+
+ secrets := []models.SingleEnvironmentVariable{}
+ for _, test := range tests {
+ secrets = append(secrets, models.SingleEnvironmentVariable{Key: test.Key, Value: test.Value})
+ }
+
+ results := SubstituteSecrets(secrets)
+
+ for index, expanded := range results {
+ if expanded.Value != tests[index].ExpectedValue {
+ t.Errorf("Test_SubstituteSecrets_When_ReferenceToSelf: expected [%s] but got [%s] for input [%s]", tests[index].ExpectedValue, expanded.Value, tests[index].Value)
+ }
+ }
+}
+
+func Test_SubstituteSecrets_When_No_SubstituteNeeded(t *testing.T) {
+
+ tests := []struct {
+ Key string
+ Value string
+ ExpectedValue string
+ }{
+ {
+ Key: "DOMAIN",
+ Value: "infisical.com",
+ ExpectedValue: "infisical.com",
+ },
+ {
+ Key: "API_KEY",
+ Value: "hdgsvjshcgkdckhevdkd",
+ ExpectedValue: "hdgsvjshcgkdckhevdkd",
+ },
+ {
+ Key: "ENV",
+ Value: "PROD",
+ ExpectedValue: "PROD",
+ },
+ }
+
+ secrets := []models.SingleEnvironmentVariable{}
+ for _, test := range tests {
+ secrets = append(secrets, models.SingleEnvironmentVariable{Key: test.Key, Value: test.Value})
+ }
+
+ results := SubstituteSecrets(secrets)
+
+ for index, expanded := range results {
+ if expanded.Value != tests[index].ExpectedValue {
+ t.Errorf("Test_SubstituteSecrets_When_ReferenceToSelf: expected [%s] but got [%s] for input [%s]", tests[index].ExpectedValue, expanded.Value, tests[index].Value)
+ }
+ }
+}
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
index ce234d12d..280dd9f79 100644
--- a/docker-compose.dev.yml
+++ b/docker-compose.dev.yml
@@ -57,6 +57,8 @@ services:
- NEXT_PUBLIC_WEBSITE_URL=${SITE_URL}
- NEXT_PUBLIC_POSTHOG_HOST=${POSTHOG_HOST}
- NEXT_PUBLIC_POSTHOG_API_KEY=${POSTHOG_PROJECT_API_KEY}
+ - NEXT_PUBLIC_STRIPE_PRODUCT_PRO=${STRIPE_PRODUCT_PRO}
+ - NEXT_PUBLIC_STRIPE_PRODUCT_STARTER=${STRIPE_PRODUCT_STARTER}
- NEXT_PUBLIC_TELEMETRY_ENABLED=${TELEMETRY_ENABLED}
networks:
- infisical-dev
diff --git a/docker-compose.yml b/docker-compose.yml
index 648da0e3d..3204f9257 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -49,6 +49,9 @@ services:
- NEXT_PUBLIC_WEBSITE_URL=${SITE_URL}
- NEXT_PUBLIC_POSTHOG_HOST=${POSTHOG_HOST}
- NEXT_PUBLIC_POSTHOG_API_KEY=${POSTHOG_PROJECT_API_KEY}
+ - NEXT_PUBLIC_STRIPE_PRODUCT_PRO=${STRIPE_PRODUCT_PRO}
+ - NEXT_PUBLIC_STRIPE_PRODUCT_STARTER=${STRIPE_PRODUCT_STARTER}
+ - NEXT_PUBLIC_TELEMETRY_ENABLED=${TELEMETRY_ENABLED}
networks:
- infisical
diff --git a/docs/getting-started/cli/installation.mdx b/docs/cli/overview.mdx
similarity index 82%
rename from docs/getting-started/cli/installation.mdx
rename to docs/cli/overview.mdx
index 5506c6aa0..bbe86d379 100644
--- a/docs/getting-started/cli/installation.mdx
+++ b/docs/cli/overview.mdx
@@ -1,10 +1,12 @@
---
-title: "Installation"
+title: "Overview"
---
-Prerequisite: [Setup an account](../../getting-started/dashboard/create-account) with Infisical Cloud or via self-hosted installation.
+Prerequisite: Set up an account with [Infisical Cloud](https://app.infisical.com) or via a [self-hosted installation](/self-hosting/overview).
-Follow the guide for your OS below to install the CLI.
+The Infisical CLI provides a way to inject environment variables from the platform into your apps and infrastructure.
+
+## Installation
@@ -18,7 +20,7 @@ Follow the guide for your OS below to install the CLI.
infisical --version
```
- To update:
+ ## Updates
```bash
brew upgrade infisical
@@ -37,7 +39,7 @@ Follow the guide for your OS below to install the CLI.
infisical --version
```
- To update:
+ ## Updates
```bash
scoop update infisical
diff --git a/docs/cli/reference/commands.mdx b/docs/cli/reference/commands.mdx
new file mode 100644
index 000000000..acefdfa7e
--- /dev/null
+++ b/docs/cli/reference/commands.mdx
@@ -0,0 +1,20 @@
+---
+title: "Commands"
+---
+
+## Commands
+
+| Command | Description |
+| ------- | -------------------------------------------------------------------- |
+| `login` | Used to authenticate and set the logged in user. |
+| `init` | Used to link a local project to the platform. |
+| `run` | Used to inject envars from the platform into an application process. |
+
+## Global options
+
+| Option | Description |
+| ----------------- | ----------------------------------------------- |
+| `--help`, `-h` | List help for any command |
+| `--debug`, `-d` | Enable verbose logging |
+| `--domain` | Use to direct Infisical to a self-hosted domain |
+| `--version`, `-v` | Print version information and quit |
diff --git a/docs/cli/reference/init.mdx b/docs/cli/reference/init.mdx
new file mode 100644
index 000000000..8d1c03061
--- /dev/null
+++ b/docs/cli/reference/init.mdx
@@ -0,0 +1,13 @@
+---
+title: "infisical init"
+---
+
+```bash
+infisical init
+```
+
+## Description
+
+Link a local project to the platform
+
+The command creates a `infisical.json` file containing your Project ID.
diff --git a/docs/cli/reference/login.mdx b/docs/cli/reference/login.mdx
new file mode 100644
index 000000000..32c1bedba
--- /dev/null
+++ b/docs/cli/reference/login.mdx
@@ -0,0 +1,13 @@
+---
+title: "infisical login"
+---
+
+```bash
+infisical login
+```
+
+## Description
+
+Verify a user and save credentials to the system keyring.
+
+To change the logged in user, run the command again to overwrite the previous login.
diff --git a/docs/cli/reference/run.mdx b/docs/cli/reference/run.mdx
new file mode 100644
index 000000000..7fb207612
--- /dev/null
+++ b/docs/cli/reference/run.mdx
@@ -0,0 +1,19 @@
+---
+title: "infisical run"
+---
+
+```bash
+infisical run [options] -- [your application start command]
+```
+
+## Description
+
+Inject environment variables from the platform into an application process.
+
+## Options
+
+| Option | Description | Default value |
+| -------------- | ----------------------------------------------------------------------------------------------------------- | ------------- |
+| `--env` | Used to set the environment that secrets are pulled from. Accepted values: `dev`, `staging`, `test`, `prod` | `dev` |
+| `--projectId` | Used to link a local project to the platform (required only if injecting via the service token method) | `None` |
+| `--expand` | Parse shell parameter expansions in your secrets (e.g., `${DOMAIN}`) | `true` |
diff --git a/docs/getting-started/cli/token.mdx b/docs/cli/token.mdx
similarity index 100%
rename from docs/getting-started/cli/token.mdx
rename to docs/cli/token.mdx
diff --git a/docs/cli/usage.mdx b/docs/cli/usage.mdx
new file mode 100644
index 000000000..ea7180068
--- /dev/null
+++ b/docs/cli/usage.mdx
@@ -0,0 +1,52 @@
+---
+title: "Usage"
+---
+
+Prerequisite: [Install the CLI](/cli/overview)
+
+## Log in to the Infisical CLI
+
+```bash
+infisical login
+```
+
+## Initialize Infisical for your project
+
+```bash
+# move to your project
+cd /path/to/project
+
+# initialize infisical
+infisical init
+```
+
+## Inject environment variables
+
+```bash
+# inject environment variables into app
+infisical run -- [your application start command]
+```
+
+Options you can specify:
+
+| Option | Description | Default value |
+| ------------- | ----------------------------------------------------------------------------------------------------------- | ------------- |
+| `--env` | Used to set the environment that secrets are pulled from. Accepted values: `dev`, `staging`, `test`, `prod` | `dev` |
+| `--projectId` | Used to link a local project to the platform (required only if injecting via the service token method) | `None` |
+| `--expand` | Parse shell parameter expansions in your secrets (e.g., `${DOMAIN}`) | `true` |
+
+## Examples:
+
+```bash
+# example with node
+infisical run -- node index.js
+
+# example with node (nodemon)
+infisical run -- nodemon index.js
+
+# example with node (nodemon) pulling in secrets from test environment
+infisical run --env=test -- nodemon index.js
+
+# example with flask
+infisical run -- flask run
+```
diff --git a/docs/contributing/architecture.mdx b/docs/contributing/architecture.mdx
deleted file mode 100644
index 0c9efc363..000000000
--- a/docs/contributing/architecture.mdx
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "Architecture"
----
-
-Infisical is an open-source collection of services for simple secret management built on top of Typescript, Javascript (ongoing conversion to TS), and Go. It's all dockerized and can be spun up with Docker Compose.
-
-
-
-## NGINX
-
-NGINX is a reverse-proxy and load balancer that sits in front of Infisical. It forwards requests to the frontend and backend services.
-
-## Frontend
-
-The frontend service renders the Web UI using Next.js.
-
-## Backend
-
-The backend service provides the back-of-house logic for secret management.
-
-## Database
-
-The (MongoDB) database stores all data and (encrypted) secrets.
-
-## CLI
-
-The platform-agnostic CLI allows you to inject environment variables from Infisical into apps and infrastructure.
diff --git a/docs/contributing/developing.mdx b/docs/contributing/developing.mdx
index 83d00d9f1..cca804a9c 100644
--- a/docs/contributing/developing.mdx
+++ b/docs/contributing/developing.mdx
@@ -40,6 +40,7 @@ docker-compose -f docker-compose.dev.yml up
The docker-compose development environment consists of:
+- nginx
- frontend
- backend
- mongo
diff --git a/docs/getting-started/cli/cli-guide.mdx b/docs/getting-started/cli/cli-guide.mdx
deleted file mode 100644
index ce0a45bdb..000000000
--- a/docs/getting-started/cli/cli-guide.mdx
+++ /dev/null
@@ -1,56 +0,0 @@
----
-title: "Usage"
----
-
-Prerequisite: [Install the CLI](../../getting-started/cli/installation)
-
-## Login
-
-Login in using the `login` command in your terminal. Logging in is a one-time, post-installation action that authenticates you with the platform — to change users, you can run the command again.
-
-```bash
-infisical login
-```
-
-## Initialization
-
-In the root of your local project, initialize Infisical and follow steps to connect your project to the platform.
-
-```bash
-cd /path/to/project
-
-# initialization
-infisical init
-```
-
-## Injecting environment variables
-
-To inject environment variables from the platform to your project, use the `run` command.
-
-```bash
-# command
-infisical run -- [your application start command]
-```
-
-Options you can specify:
-
-| Option | Description | Default value |
-| ------------- | ----------------------------------------------------------------------------------------------------------- | ------------- |
-| `--env` | Used to set the environment that secrets are pulled from. Accepted values: `dev`, `staging`, `test`, `prod` | `dev` |
-| `--projectId` | Used to link a local project to the platform (required only if injecting via the service token method) | `None` |
-
-Examples:
-
-```bash
-# example with node
-infisical run -- node index.js
-
-# example with node (nodemon)
-infisical run -- nodemon index.js
-
-# example with node (nodemon) pulling in secrets from test environment
-infisical run --env=test -- nodemon index.js
-
-# example with flask
-infisical run -- flask run
-```
diff --git a/docs/getting-started/cli/reference.mdx b/docs/getting-started/cli/reference.mdx
deleted file mode 100644
index c0bc557cd..000000000
--- a/docs/getting-started/cli/reference.mdx
+++ /dev/null
@@ -1,55 +0,0 @@
----
-title: "Reference"
----
-
-## Commands
-
-| Command | Description | Options |
-| ------- | -------------------------------------------------------------------- | ---------------------- |
-| `login` | Used to authenticate and set the logged in user. |
-| `init` | Used to link a local project to the platform. |
-| `run` | Used to inject envars from the platform into an application process. | `--projectId`, `--env` |
-
-## Global options
-
-| Option | Description |
-| ----------------- | ---------------------------------- |
-| `--help`, `-h` | List help for any command |
-| `--debug`, `-d` | Enable verbose logging |
-| `--domain` | Use to direct Infisical to |
-| `--version`, `-v` | Print version information and quit |
-
-### Login
-
-Used to authenticate and set the logged in user.
-
-Post-authentication credentials are saved securely in your system keyring. Since only one user can be logged in at a time, to change the logged in user, run the command again to overwrite the previous login.
-
-```bash
-infisical login
-```
-
-### Init
-
-Used to link a local project to the platform (cloud or self-hosted)
-
-Run this command at the root of your local project. You will have to run this command for each new project you create locally.
-
-```bash
-infisical init
-```
-
-### Run
-
-Used to inject environment variables from the platform into an application process.
-
-```bash
-infisical run [options] -- [your application start command]
-```
-
-Options you can specify:
-
-| Option | Description | Default value |
-| ------------- | ----------------------------------------------------------------------------------------------------------- | ------------- |
-| `--env` | Used to set the environment that secrets are pulled from. Accepted values: `dev`, `staging`, `test`, `prod` | `dev` |
-| `--projectId` | Used to link a local project to the platform (required only if injecting via the service token method) | `None` |
diff --git a/docs/getting-started/dashboard/create-account.mdx b/docs/getting-started/dashboard/create-account.mdx
index c71a748e0..ea412c1e7 100644
--- a/docs/getting-started/dashboard/create-account.mdx
+++ b/docs/getting-started/dashboard/create-account.mdx
@@ -4,7 +4,7 @@ title: "Sign up"
## Self-hosted
-If you're using a self-hosted installation, follow the [setup](/self-hosting/overview) then open your website URL `{WEBSITE_URL}/login`.
+If you're using a self-hosted installation, follow the [setup](/self-hosting/overview) then open your site URL `{SITE_URL}`.
## Infisical Cloud
diff --git a/docs/getting-started/dashboard/integrations.mdx b/docs/getting-started/dashboard/integrations.mdx
index 2a4791af4..193cde84b 100644
--- a/docs/getting-started/dashboard/integrations.mdx
+++ b/docs/getting-started/dashboard/integrations.mdx
@@ -8,6 +8,6 @@ We’re still early with integrations but you’ll be able to sync environment v
Check out integrations:
-- Heroku
-- Docker
-- Docker Compose
+- [Heroku](/integrations/heroku)
+- [Docker](/integrations/docker)
+- [Docker Compose](/integrations/docker-compose)
diff --git a/docs/getting-started/dashboard/token.mdx b/docs/getting-started/dashboard/token.mdx
index c2f98c77f..121578417 100644
--- a/docs/getting-started/dashboard/token.mdx
+++ b/docs/getting-started/dashboard/token.mdx
@@ -4,11 +4,11 @@ title: "Infisical Token"
An Infisical Token is needed to authenticate the CLI when there isn't an easy way to manually type in your login credentials to sync environment variables to your applications.
-It grants read-only access to a particular environment and project for a specified amount of time; once the token expires, any CLI application that relies on it for authentication will be denied access to retrieve related secrets.
+It grants read-only access to a particular environment and project for a specified amount of time.
This is useful in the following contexts:
-- [Docker](../../integrations/docker)/[Docker-Compose](../../integrations/docker-compose) integration: An Infisical Token can be passed to a Docker container as an environment variable for the CLI to authenticate and pull its corresponding secrets.
+- [Docker](/integrations/docker)/[Docker-Compose](/integrations/docker-compose) integration: An Infisical Token can be passed to a Docker container as an environment variable for the CLI to authenticate and pull its corresponding secrets.
## Generate an Infisical Token
@@ -19,5 +19,3 @@ It's possible to generate an Infisical token in the settings of a project.


-
-To use the Infisical Token in the CLI, check out the docs for that [here](../../getting-started/cli/token).
diff --git a/docs/getting-started/features.mdx b/docs/getting-started/features.mdx
index 9ba45b25b..c520dd905 100644
--- a/docs/getting-started/features.mdx
+++ b/docs/getting-started/features.mdx
@@ -20,46 +20,24 @@ The CLI is used to inject environment variables into applications and infrastruc
- Inject environment variables.
- Inject environment variables into containers via service tokens for Docker.
-## Integrations
-
-We're still early with integrations but you'll be able to sync environment variables across your entire infrastructure from local development to CI/CD and production.
-
-| Integration | Status |
-| -------------- | ----------- |
-| Docker | Available |
-| Docker-Compose | Available |
-| Kubernetes | Coming soon |
-| Vercel | Coming soon |
-| AWS | Coming soon |
-| GCP | Coming soon |
-| Azure | Coming soon |
-| DigitalOcean | Coming soon |
-| GitLab | Coming soon |
-| CircleCI | Coming soon |
-| TravisCI | Coming soon |
-| GitHub Actions | Coming soon |
-| Jenkins | Coming soon |
-
-Missing an integration? Throw in a request.
-
## Roadmap
We're building the future of secret management, one that's comprehensive and accessible to all. Some high-level features we have in mind:
-| Feature | Status |
-| ------------------------------------- | --------------- |
-| Integrations | Ongoing |
-| More hosting options | Ongoing |
-| 1-Click Deploys | Ongoing |
-| Account recovery: Backup key | Ongoing |
-| Account recovery: Member-assisted | Not yet started |
-| Slack & MS teams integrations | Not yet started |
-| Access logs | Not yet started |
-| Version control for secrets | Not yet started |
-| 2FA | Not yet started |
-| Restricted IPs | Not yet started |
-| Read/write access controls | Not yet started |
-| Secret rotation | Not yet started |
-| Comparing secrets across environments | Not yet started |
+| Feature | Status |
+| ------------------------------------- | ----------- |
+| Integrations | Ongoing |
+| More hosting options | Ongoing |
+| 1-Click Deploys | Ongoing |
+| Account recovery: Backup key | Ongoing |
+| Account recovery: Member-assisted | Coming soon |
+| Slack & MS teams integrations | Coming soon |
+| Access logs | Coming soon |
+| Version control for secrets | Coming soon |
+| 2FA | Coming soon |
+| Restricted IPs | Coming soon |
+| Read/write access controls | Coming soon |
+| Secret rotation | Coming soon |
+| Comparing secrets across environments | Coming soon |
-Interested in contributing? Check out the guide.
+Interested in contributing? Check out the [guide](/contributing/overview).
diff --git a/docs/getting-started/introduction.mdx b/docs/getting-started/introduction.mdx
index 7f5a6cb2a..5f5d2a44d 100644
--- a/docs/getting-started/introduction.mdx
+++ b/docs/getting-started/introduction.mdx
@@ -2,20 +2,36 @@
title: "Introduction"
---
-
+Infisical is an [open-source](https://opensource.com/resources/what-open-source), [end-to-end encrypted](https://en.wikipedia.org/wiki/End-to-end_encryption) secret manager that enables teams to easily manage and sync their environment variables.
-Infisical is an [open-source](https://opensource.com/resources/what-open-source), end-to-end encrypted (E2EE) secret manager that enables teams to easily manage and sync their environment variables.
+Start syncing environment variables with [Infisical Cloud](https://app.infisical.com) or learn how to [host Infisical](/self-hosting/overview) yourself.
-It stops [secret sprawl](https://www.gitguardian.com/glossary/secret-sprawl-definition) by providing a single source-of-truth for environment variables. It offers a dashboard for teams to manage environment variables and a platform-agnostic CLI to inject them into apps and infrastructure.
-
-Some problems we solve:
-
-- Leaking .env files to version control.
-- Debugging missing environment variables.
-- Sending environment variables over email.
-
-Infisical uses [end-to-end encryption](https://en.wikipedia.org/wiki/End-to-end_encryption) to ensure that only designated team members can read their environment variables; unless intended for specific integrations, environment variables are always encrypted before being sent to the server.
+
+
+ Tour Infisical in a few minutes.
+
+
+ Install the CLI to inject secrets into apps and infra.
+
+
+ Learn how to configure and deploy Infisical.
+
+
+ Explore integrations for Docker, AWS, Heroku, etc.
+
+
diff --git a/docs/getting-started/quickstart.mdx b/docs/getting-started/quickstart.mdx
new file mode 100644
index 000000000..307127ab2
--- /dev/null
+++ b/docs/getting-started/quickstart.mdx
@@ -0,0 +1,43 @@
+---
+title: "Quickstart"
+---
+
+This example demonstrates how to store and inject environment variables from [Infisical Cloud](https://app.infisical.com) into your application.
+
+Note that the Infisical CLI is platform-agnostic and can inject environment variables across many tech stacks and frameworks.
+
+## Set up Infisical Cloud
+
+1. Login or create an accout at `app.infisical.com`.
+2. Create a new project.
+3. Populate your environment variables as in the image below.
+
+
+
+## Set up the CLI
+
+1. Follow the instructions to [install the CLI](/cli/overview).
+
+2. Initialize Infisical for your project.
+
+```bash
+# move to your project
+cd /path/to/project
+
+# initialize infisical
+infisical init
+```
+
+## Start your app with environment variables injected
+
+```bash
+# inject environment variables into app
+infisical run -- [your application start command]
+```
+
+
+ Check out our [integrations](/integrations/overview) for injecting environment
+ variables into frameworks and platforms like Docker.
+
+
+Your app should be running with the environment variables injected.
diff --git a/docs/getting-started/security/statement.mdx b/docs/getting-started/security/statement.mdx
deleted file mode 100644
index 60f6c2bd5..000000000
--- a/docs/getting-started/security/statement.mdx
+++ /dev/null
@@ -1,11 +0,0 @@
----
-title: "Statement"
----
-
-As a secrets manager, we are deeply committed to enforcing the privacy and security of all users and data on the platform but acknowledge that it is virtually impossible to guarantee perfect security; unfortunately, even the most secure systems have vulnerabilities.
-
-As part of our commitment, we do our best to maintain platform privacy and security, notify users if anything goes wrong, and rectify adverse situations immediately if anything happens. As Infisical grows, we will be adding more opt-in security measures to ensure better data protection and maintain trust within the growing community. With that, let’s make the most simple and secure secrets management system out there!
-
-Best,
-
-Infisical Team
diff --git a/docs/images/project-quickstart.png b/docs/images/project-quickstart.png
new file mode 100644
index 000000000..6d8d7f664
Binary files /dev/null and b/docs/images/project-quickstart.png differ
diff --git a/docs/integrations/docker-compose.mdx b/docs/integrations/docker-compose.mdx
index a7310ad85..97ce0aba0 100644
--- a/docs/integrations/docker-compose.mdx
+++ b/docs/integrations/docker-compose.mdx
@@ -3,23 +3,26 @@ title: "Docker Compose"
---
### Step 1: Add CLI to your Dockerfile
-Follow steps 1 through 3 on our [guide to configure Infisical CLI](/docker) in your Dockerfile.
+
+Follow steps 1 through 3 on our [guide to configure Infisical CLI](../getting-started/cli/installation) in your Dockerfile.
### Step 2: Generate Infisical Token
+
In order for Infisical CLI to authenticate and retrieve your project's secrets without exposing your login credentials, you must generate a Infisical Token.
-To learn how, visit [Infisical Token](../getting-started/cli/infisical-token). Once you have generated the token, keep it handy.
+To learn how, visit [Infisical Token](../getting-started/cli/infisical-token). Once you have generated the token, keep it handy.
-If you have multiple services and they do not use the same secrets, you will have to generate a Infisical Token for each service.
+ If you have multiple services and they do not use the same secrets, you will
+ have to generate a Infisical Token for each service.
### Step 3: Tell Docker Compose your Infisical Token
+
For each service you want to inject secrets into, set an environment variable called `INFISICAL_TOKEN` equal to a helpful identifier variable.
-This will ensure that you can set Infisical Tokens for multiple services.
+This will ensure that you can set Infisical Tokens for multiple services.
For the example below, we have set `INFISICAL_TOKEN_FOR_WEB` and `INFISICAL_TOKEN_FOR_API` as the `INFISICAL_TOKEN` for the corresponding service.
-
```yaml
# Example Docker Compose file
services:
@@ -36,13 +39,14 @@ services:
container_name: auledge-backend
environment:
- INFISICAL_TOKEN=${INFISICAL_TOKEN_FOR_API}
-
```
-### 4: Export shell variables
-Next, set the shell variables you defined in your compose file. This can be done manually or via your CI/CD environment. Once done, it will be used to populate the corresponding `INFISICAL_TOKEN`
-in your Docker Compose file.
-``` bash
+### 4: Export shell variables
+
+Next, set the shell variables you defined in your compose file. This can be done manually or via your CI/CD environment. Once done, it will be used to populate the corresponding `INFISICAL_TOKEN`
+in your Docker Compose file.
+
+```bash
#Example
# Token refers to the token we generated in step 2 for this service
@@ -51,6 +55,6 @@ export INFISICAL_TOKEN_FOR_WEB=
# Token refers to the token we generated in step 2 for this service
export INFISICAL_TOKEN_FOR_API=
-# Then run your compose file in the same terminal.
+# Then run your compose file in the same terminal.
docker-compose ...
```
diff --git a/docs/integrations/docker.mdx b/docs/integrations/docker.mdx
index 7d66f3db6..aad94ae6c 100644
--- a/docs/integrations/docker.mdx
+++ b/docs/integrations/docker.mdx
@@ -2,8 +2,6 @@
title: "Docker"
---
-Prerequisite: [Infisical Token and How to Generate One](../../getting-started/dashboard/token).
-
## Step 1: Add CLI to your Dockerfile
@@ -33,7 +31,7 @@ Prerequisite: [Infisical Token and How to Generate One](../../getting-started/da
## Step 2: Generate Infisical Token
-In order for the CLI to authenticate and retrieve your project's secrets without requiring your login credentials, you must [generate an Infisical Token](../../getting-started/dashboard/token); keep it handy.
+[Generate an Infisical Token](../../getting-started/dashboard/token) and keep it handy.
## Step 3: Set start command of your container
@@ -56,7 +54,7 @@ Required options:
The CLI looks out for an environment variable called the `INFISICAL_TOKEN` which you can set depending on where you run the CLI. If `INFISICAL_TOKEN` is detected by the CLI, it will authenticate and retrieve the environment variables which the token is authorized for.
```bash
- docker run --env INFISICAL_TOKEN=...
+ docker run --env INFISICAL_TOKEN=[the-token-you-got-from-step-2]...
```
Note: `INFISICAL_TOKEN` is the token you generated in step 2.
diff --git a/docs/integrations/heroku.mdx b/docs/integrations/heroku.mdx
index e15dbd20e..5f0debd3e 100644
--- a/docs/integrations/heroku.mdx
+++ b/docs/integrations/heroku.mdx
@@ -5,20 +5,22 @@ description: "With this integration, you can automatically sync your secrets to
## Instructions
-### Step 1: Open the integrations csonsole
+### Step 1: Open the integrations console
Open the Infisical Dashboard. Choose the project in which you want to set up the intergation. Go to the integrations tab in the left sidebar.
### Step 2: Authenticate with Heroku
-Click on Heroku in the list of available integrations. Log in if asked by Heroku and provide the necessary permissions to Infisical. You will afterwards be redirected back to the integrations page.
+Click on "Heroku" tile. Log in if required and provide the necessary permissions to Infisical. You will afterwards be redirected back to the integrations page.
-Note: during an integration with Heroku, for security reasons, it is impossible to maintain end-to-end encryption. In theory, this lets Infisical decrypt yor environment variables. In practice, we can assure you that this will never be done, and it allows us to protect your secrets from bad actors online. The core Infisical service will always stay end-to-end encrypted. With any questions, reach out support@infisical.com.
+Note: during an integration with Heroku, for security reasons, it is impossible to maintain end-to-end encryption. In theory, this lets Infisical decrypt yor environment variables. In practice, we can assure you that this will never be done, and it allows us to protect your secrets from bad actors online. With any questions, reach out support@infisical.com.
### Step 3: Start integration
-Once the integration is set up, choose a Heroku App that you want to sync the secrets to, and the Infisical project environment that you would to sync the secrets from. Click on the "Start Integration" button.
+Choose a Heroku App that you want to sync the secrets to, and the Infisical project environment that you want to sync the secrets from. Start the integration.
-### Step 4: You're good to go!
+The integration should now show status 'In Sync'. Every time you edit secrets, they will be automatically pushed to Heroku.
-The integration should now show status 'In Sync'. Every time you edit the secrets, they will be automatically pushed to Heroku. If you want to update anything in your integration, you will have to delete the current one and create a new one.
+
+ If you need to update your integration, you will have to delete the current one and create a new one.
+
diff --git a/docs/integrations/overview.mdx b/docs/integrations/overview.mdx
new file mode 100644
index 000000000..4f4a2db3e
--- /dev/null
+++ b/docs/integrations/overview.mdx
@@ -0,0 +1,24 @@
+---
+title: "Overview"
+---
+
+Integrations allow environment variables to be synced across your entire infrastructure from local development to CI/CD and production.
+
+Missing an integration? Throw in a [request](https://github.com/Infisical/infisical/issues).
+
+| Integration | Status |
+| ---------------------------------------------- | ----------- |
+| [Docker](/integrations/docker) | Available |
+| [Docker-Compose](/integrations/docker-compose) | Available |
+| [Heroku](/integrations/heroku) | Available |
+| Kubernetes | Coming soon |
+| Vercel | Coming soon |
+| AWS | Coming soon |
+| GCP | Coming soon |
+| Azure | Coming soon |
+| DigitalOcean | Coming soon |
+| GitLab | Coming soon |
+| CircleCI | Coming soon |
+| TravisCI | Coming soon |
+| GitHub Actions | Coming soon |
+| Jenkins | Coming soon |
diff --git a/docs/mint.json b/docs/mint.json
index 5412de97d..baea4bbe3 100644
--- a/docs/mint.json
+++ b/docs/mint.json
@@ -35,17 +35,22 @@
],
"navigation": [
{
- "group": "Platform",
+ "group": " ",
"pages": [
- "getting-started/introduction",
- "getting-started/features",
+ {
+ "group": "Overview",
+ "pages": [
+ "getting-started/introduction",
+ "getting-started/quickstart",
+ "getting-started/features"
+ ]
+ },
{
"group": "Security",
"pages": [
- "getting-started/security/overview",
- "getting-started/security/data-model",
- "getting-started/security/mechanics",
- "getting-started/security/statement"
+ "security/overview",
+ "security/data-model",
+ "security/mechanics"
]
},
{
@@ -56,49 +61,56 @@
"getting-started/dashboard/project",
"getting-started/dashboard/integrations",
"getting-started/dashboard/token"
- ]
+ ]
},
{
- "group": "Command Line",
+ "group": "CLI",
"pages": [
- "getting-started/cli/installation",
- "getting-started/cli/cli-guide",
- "getting-started/cli/token",
- "getting-started/cli/reference"
+ "cli/overview",
+ "cli/usage",
+ {
+ "group": "Reference",
+ "pages": [
+ "cli/reference/commands",
+ "cli/reference/login",
+ "cli/reference/init",
+ "cli/reference/run"
+ ]
+ }
]
- }
- ]
- },
- {
- "group": "Integrations",
- "pages": [
- "integrations/heroku",
- "integrations/docker",
- "integrations/docker-compose"
- ]
- },
- {
- "group": "Self-hosting",
- "pages": [
- "self-hosting/overview",
- {
- "group": "Deployments",
- "pages": ["self-hosting/deployments/linux"]
},
{
- "group": "Configuration",
- "pages": ["self-hosting/configuration/envars"]
+ "group": "Integrations",
+ "pages": [
+ "integrations/overview",
+ "integrations/heroku",
+ "integrations/docker",
+ "integrations/docker-compose"
+ ]
+ },
+ {
+ "group": "Self-hosting",
+ "pages": [
+ "self-hosting/overview",
+ {
+ "group": "Deployments",
+ "pages": ["self-hosting/deployments/linux"]
+ },
+ {
+ "group": "Configuration",
+ "pages": ["self-hosting/configuration/envars"]
+ }
+ ]
+ },
+ {
+ "group": "Contributing",
+ "pages": [
+ "contributing/overview",
+ "contributing/code-of-conduct",
+ "contributing/developing"
+ ]
}
]
- },
- {
- "group": "Contributing",
- "pages": [
- "contributing/overview",
- "contributing/code-of-conduct",
- "contributing/developing",
- "contributing/architecture"
- ]
}
],
"backgroundImage": "/images/background.png"
diff --git a/docs/getting-started/security/data-model.mdx b/docs/security/data-model.mdx
similarity index 100%
rename from docs/getting-started/security/data-model.mdx
rename to docs/security/data-model.mdx
diff --git a/docs/getting-started/security/mechanics.mdx b/docs/security/mechanics.mdx
similarity index 100%
rename from docs/getting-started/security/mechanics.mdx
rename to docs/security/mechanics.mdx
diff --git a/docs/getting-started/security/overview.mdx b/docs/security/overview.mdx
similarity index 70%
rename from docs/getting-started/security/overview.mdx
rename to docs/security/overview.mdx
index edb95f406..b4e1169df 100644
--- a/docs/getting-started/security/overview.mdx
+++ b/docs/security/overview.mdx
@@ -18,3 +18,13 @@ In subsequent sections, we refer:
- To users uploading their secrets to Infisical as “senders” and those receiving secrets as “receivers". For instance, if Bob and Alice are both enrolled in a project and Bob adds new secrets to the project to be pulled by Alice, then Bob is considered to be the sender and Alice the receiver.
- To any activity involving uploading or modifying secrets to Infisical as "pushing" and fetching secrets from Infisical as "pulling."
+
+## Statement
+
+As a secrets manager, we are deeply committed to enforcing the privacy and security of all users and data on the platform but acknowledge that it is virtually impossible to guarantee perfect security; unfortunately, even the most secure systems have vulnerabilities.
+
+As part of our commitment, we do our best to maintain platform privacy and security, notify users if anything goes wrong, and rectify adverse situations immediately if anything happens. As Infisical grows, we will be adding more opt-in security measures to ensure better data protection and maintain trust within the growing community. With that, let’s make the most simple and secure secrets management system out there!
+
+Best,
+
+Infisical Team
diff --git a/docs/self-hosting/overview.mdx b/docs/self-hosting/overview.mdx
index 0c0cb99cf..8f2df5c37 100644
--- a/docs/self-hosting/overview.mdx
+++ b/docs/self-hosting/overview.mdx
@@ -17,6 +17,10 @@ Infisical Cloud also comes with some extra features unavailabe in the self-hoste
Infisical can be deployed on a Linux VM with docker-compose. We're rolling out more specific deployment options for DigitalOcean, AWS, GCP, and Azure soon.
+Options:
+
+- [Linux VM](/self-hosting/deployments/linux)
+
## Telemetry
Infisical collects telemetry data about general usage.
diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json
new file mode 100644
index 000000000..0c5504b90
--- /dev/null
+++ b/frontend/.eslintrc.json
@@ -0,0 +1,46 @@
+{
+ "extends": "next/core-web-vitals",
+ "plugins": [
+ "simple-import-sort"
+ ],
+ "rules": {
+ "react-hooks/exhaustive-deps": "off",
+ "simple-import-sort/exports": "warn",
+ "simple-import-sort/imports": [
+ "warn",
+ {
+ "groups": [
+ // Node.js builtins. You could also generate this regex if you use a `.js` config.
+ // For example: `^(${require("module").builtinModules.join("|")})(/|$)`
+ // Note that if you use the `node:` prefix for Node.js builtins,
+ // you can avoid this complexity: You can simply use "^node:".
+ [
+ "^(assert|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|https|module|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|tty|url|util|vm|zlib|freelist|v8|process|async_hooks|http2|perf_hooks)(/.*|$)"
+ ],
+ // Packages `react` related packages
+ [
+ "^react",
+ "^next",
+ "^@?\\w"
+ ],
+ // Internal packages.
+ [
+ "^~(/.*|$)"
+ ],
+ // Relative imports
+ [
+ "^\\.\\.(?!/?$)",
+ "^\\.\\./?$",
+ "^\\./(?=.*/)(?!/?$)",
+ "^\\.(?!/?$)",
+ "^\\./?$"
+ ],
+ // Style imports.
+ [
+ "^.+\\.?(css|scss)$"
+ ]
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/frontend/.prettierrc b/frontend/.prettierrc
index 8dc2e7263..222861c34 100644
--- a/frontend/.prettierrc
+++ b/frontend/.prettierrc
@@ -1,4 +1,4 @@
{
- "tabWidth": 4,
- "useTabs": true
+ "tabWidth": 2,
+ "useTabs": false
}
diff --git a/frontend/components/RouteGuard.js b/frontend/components/RouteGuard.js
index bedf124cc..a21c0c86a 100644
--- a/frontend/components/RouteGuard.js
+++ b/frontend/components/RouteGuard.js
@@ -1,82 +1,84 @@
-import { useState, useEffect } from "react";
-import { useRouter } from "next/router";
-import checkAuth from "../pages/api/auth/CheckAuth";
+import { useEffect, useState } from "react";
import Image from "next/image";
-import { publicPaths } from "../const";
+import { useRouter } from "next/router";
+
+import { publicPaths } from "~/const";
+import checkAuth from "~/pages/api/auth/CheckAuth";
// #TODO: finish spinner only when the data loads fully
// #TODO: Redirect somewhere if the page does not exist
export default function RouteGuard({ children }) {
- const router = useRouter();
- const [authorized, setAuthorized] = useState(false);
+ const router = useRouter();
+ const [authorized, setAuthorized] = useState(false);
- useEffect(async () => {
- // on initial load - run auth check
- await authCheck(router.asPath);
+ useEffect(() => {
+ // on initial load - run auth check
+ (async () => {
+ await authCheck(router.asPath);
+ })();
- // on route change start - hide page content by setting authorized to false
- // #TODO: add the loading page when not yet authorized.
- const hideContent = () => setAuthorized(false);
- // const onError = () => setAuthorized(true)
- router.events.on("routeChangeStart", hideContent);
- // router.events.on("routeChangeError", onError);
+ // on route change start - hide page content by setting authorized to false
+ // #TODO: add the loading page when not yet authorized.
+ const hideContent = () => setAuthorized(false);
+ // const onError = () => setAuthorized(true)
+ router.events.on("routeChangeStart", hideContent);
+ // router.events.on("routeChangeError", onError);
- // on route change complete - run auth check
- router.events.on("routeChangeComplete", authCheck);
+ // on route change complete - run auth check
+ router.events.on("routeChangeComplete", authCheck);
- // unsubscribe from events in useEffect return function
- return () => {
- router.events.off("routeChangeStart", hideContent);
- router.events.off("routeChangeComplete", authCheck);
- // router.events.off("routeChangeError", onError);
- };
+ // unsubscribe from events in useEffect return function
+ return () => {
+ router.events.off("routeChangeStart", hideContent);
+ router.events.off("routeChangeComplete", authCheck);
+ // router.events.off("routeChangeError", onError);
+ };
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
+ /**
+ * redirect to login page if accessing a private page and not logged in
+ * @param {*} url - the url of the page we are trying to go to
+ */
+ async function authCheck(url) {
+ // Make sure that we don't redirect when the user is on the following pages.
+ const path = "/" + url.split("?")[0].split("/")[1];
- /**
- * redirect to login page if accessing a private page and not logged in
- * @param {*} url - the url of the page we are trying to go to
- */
- async function authCheck(url) {
- // Make sure that we don't redirect when the user is on the following pages.
- const path = "/" + url.split("?")[0].split("/")[1];
+ // Check if the user is authenticated
+ const response = await checkAuth();
+ // #TODO: figure our why sometimes it doesn't output a response
+ if (!publicPaths.includes(path)) {
+ try {
+ if (response.status !== 200) {
+ router.push("/login");
+ console.log("Unauthorized to access.");
+ setAuthorized(false);
+ } else {
+ setAuthorized(true);
+ console.log("Authorized to access.");
+ }
+ } catch (error) {
+ console.log(
+ "Error (probably the authCheck route is stuck again...):",
+ error
+ );
+ }
+ }
+ }
- // Check if the user is authenticated
- const response = await checkAuth();
- // #TODO: figure our why sometimes it doesn't output a response
- if (!publicPaths.includes(path)) {
- try {
- if (response.status !== 200) {
- router.push("/login");
- console.log("Unauthorized to access.");
- setAuthorized(false);
- } else {
- setAuthorized(true);
- console.log("Authorized to access.");
- }
- } catch (error) {
- console.log(
- "Error (probably the authCheck route is stuck again...):",
- error
- );
- }
- }
- }
-
- if (authorized) {
- return children;
- } else {
- return (
-
-
-
- );
- }
-}
\ No newline at end of file
+ if (authorized) {
+ return children;
+ } else {
+ return (
+
+
+
+ );
+ }
+}
diff --git a/frontend/components/aes-256-gcm.js b/frontend/components/aes-256-gcm.js
deleted file mode 100644
index e5c447fd5..000000000
--- a/frontend/components/aes-256-gcm.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @fileoverview Provides easy encryption/decryption methods using AES 256 GCM.
- */
-
-"use strict";
-
-const crypto = require("crypto");
-
-const ALGORITHM = "aes-256-gcm";
-const BLOCK_SIZE_BYTES = 16; // 128 bit
-
-/**
- * Provides easy encryption/decryption methods using AES 256 GCM.
- */
-class Aes256Gcm {
- /**
- * No need to run the constructor. The class only has static methods.
- */
- constructor() {}
-
- /**
- * Encrypts text with AES 256 GCM.
- * @param {string} text - Cleartext to encode.
- * @param {string} secret - Shared secret key, must be 32 bytes.
- * @returns {object}
- */
- static encrypt(text, secret) {
- const iv = crypto.randomBytes(BLOCK_SIZE_BYTES);
- const cipher = crypto.createCipheriv(ALGORITHM, secret, iv);
-
- let ciphertext = cipher.update(text, "utf8", "base64");
- ciphertext += cipher.final("base64");
- return {
- ciphertext,
- iv: iv.toString("base64"),
- tag: cipher.getAuthTag().toString("base64"),
- };
- }
-
- /**
- * Decrypts AES 256 CGM encrypted text.
- * @param {string} ciphertext - Base64-encoded ciphertext.
- * @param {string} iv - The base64-encoded initialization vector.
- * @param {string} tag - The base64-encoded authentication tag generated by getAuthTag().
- * @param {string} secret - Shared secret key, must be 32 bytes.
- * @returns {string}
- */
- static decrypt(ciphertext, iv, tag, secret) {
- const decipher = crypto.createDecipheriv(
- ALGORITHM,
- secret,
- Buffer.from(iv, "base64")
- );
- decipher.setAuthTag(Buffer.from(tag, "base64"));
-
- let cleartext = decipher.update(ciphertext, "base64", "utf8");
- cleartext += decipher.final("utf8");
-
- return cleartext;
- }
-}
-
-module.exports = Aes256Gcm;
diff --git a/frontend/components/analytics/posthog.js b/frontend/components/analytics/posthog.js
index 5eda4de3a..c8d51ad1b 100644
--- a/frontend/components/analytics/posthog.js
+++ b/frontend/components/analytics/posthog.js
@@ -1,14 +1,20 @@
import posthog from "posthog-js";
-import { ENV, POSTHOG_API_KEY, POSTHOG_HOST, TELEMETRY_ENABLED } from "../utilities/config";
+
+import {
+ ENV,
+ POSTHOG_API_KEY,
+ POSTHOG_HOST,
+ TELEMETRY_ENABLED,
+} from "../utilities/config";
export const initPostHog = () => {
- if (typeof window !== "undefined") {
- if (ENV == "production" && TELEMETRY_ENABLED) {
- posthog.init(POSTHOG_API_KEY, {
- api_host: POSTHOG_HOST,
- });
- }
- }
+ if (typeof window !== "undefined") {
+ if (ENV == "production" && TELEMETRY_ENABLED) {
+ posthog.init(POSTHOG_API_KEY, {
+ api_host: POSTHOG_HOST,
+ });
+ }
+ }
- return posthog;
+ return posthog;
};
diff --git a/frontend/components/basic/Error.js b/frontend/components/basic/Error.js
index ad058b701..78a181016 100644
--- a/frontend/components/basic/Error.js
+++ b/frontend/components/basic/Error.js
@@ -1,19 +1,17 @@
import React, { useState } from "react";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faExclamationTriangle } from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
export default function Error({ text }) {
- return (
-
-
-
-
-
-
+ function copyToClipboard() {
+ // Get the text field
+ var copyText = document.getElementById("serviceToken");
-
-
-
- {serviceToken == ""
- ?
-
- Add a service token for {workspaceName}
-
-
-
-
- Specify the name, environment, and expiry period. When a token is generated, you will only be able to see it once before it disappears. Make sure to save it somewhere.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- :
-
- Copy your service token
-
-
-
-
- Once you close this popup, you will never see your service token again
-
-
-
-
-
-
-
{serviceToken}
-
-
-
- Click to Copy
-
-
-
-
-
-
-
- }
-
-
-
-
-
-
- );
+ // Select the text field
+ copyText.select();
+ copyText.setSelectionRange(0, 99999); // For mobile devices
+
+ // Copy the text inside the text field
+ navigator.clipboard.writeText(copyText.value);
+
+ setServiceTokenCopied(true);
+ setTimeout(() => setServiceTokenCopied(false), 2000);
+ // Alert the copied text
+ // alert("Copied the text: " + copyText.value);
+ }
+
+ const closeAddServiceTokenModal = () => {
+ closeModal();
+ setServiceTokenName("");
+ setServiceToken("");
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ {serviceToken == "" ? (
+
+
+ Add a service token for {workspaceName}
+
+
+
+
+ Specify the name, environment, and expiry period. When
+ a token is generated, you will only be able to see it
+ once before it disappears. Make sure to save it
+ somewhere.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ) : (
+
+
+ Copy your service token
+
+
+
+
+ Once you close this popup, you will never see your
+ service token again
+
+
+ );
}
diff --git a/frontend/components/dashboard/DashboardInputField.js b/frontend/components/dashboard/DashboardInputField.js
index 556e64a2c..53733c38b 100644
--- a/frontend/components/dashboard/DashboardInputField.js
+++ b/frontend/components/dashboard/DashboardInputField.js
@@ -1,111 +1,131 @@
-import React from "react";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import React, { Fragment } from "react";
import { faCircle } from "@fortawesome/free-solid-svg-icons";
-import guidGenerator from "../utilities/randomId";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import guidGenerator from "../utilities/randomId";
/**
* This function splits the input of a dashboard field into the parts that are inside and outside of ${...}
* @param {string} text - the value of the input in the Dashboard Input Field
- * @returns
+ * @returns
*/
const findReferences = (text) => {
- var splitText = text.split('${');
- let textArray = [splitText[0]];
- for (var i = 1; i < splitText.length; i++) {
- let insideBrackets = "${" + splitText[i].split('}')[0]
- if (splitText[i].includes('}')) {
- insideBrackets += "}"
- }
- textArray.push(insideBrackets)
- textArray.push(splitText[i].split('}')[1])
- }
- return textArray;
-}
+ var splitText = text.split("${");
+ let textArray = [splitText[0]];
+ for (var i = 1; i < splitText.length; i++) {
+ let insideBrackets = "${" + splitText[i].split("}")[0];
+ if (splitText[i].includes("}")) {
+ insideBrackets += "}";
+ }
+ textArray.push(insideBrackets);
+ textArray.push(splitText[i].split("}")[1]);
+ }
+ return textArray;
+};
/**
* This component renders the input fields on the dashboard
- * @param {object} obj - the order number of a keyPair
- * @param {number} obj.index - the order number of a keyPair
+ * @param {object} obj - the order number of a keyPair
+ * @param {number} obj.index - the order number of a keyPair
* @param {function} obj.onChangeHandler - what happens when the input is modified
* @param {string} obj.type - whether the input field is for a Key Name or for a Key Value
- * @param {string} obj.value - value of the InputField
+ * @param {string} obj.value - value of the InputField
* @param {boolean} obj.blurred - whether the input field should be blurred (behind the gray dots) or not; this can be turned on/off in the dashboard
- * @returns
+ * @returns
*/
-const DashboardInputField = ({index, onChangeHandler, type, value, blurred}) => {
- if (type === "varName") {
- return (
-
- You don't have any integrations set up yet. When you do, they will appear here.
-
-
- To start, click on any of the options below. It takes 5 clicks to set up.
-
-
-
- }
-
-
-
- Available Integrations
-
-
-
- Click on the itegration you want to connect. This will let your environment variables flow automatically into selected third-party services.
-
-
- Note: during an integration with Heroku, for security reasons, it is impossible to maintain end-to-end encryption. In theory, this lets Infisical decrypt yor environment variables. In practice, we can assure you that this will never be done, and it allows us to protect your secrets from bad actors online. The core Infisical service will always stay end-to-end encrypted. With any questions, reach out support@infisical.com.
-
+ You {"don't"} have any integrations set up yet. When you do,
+ they will appear here.
+
+
+ To start, click on any of the options below. It takes 5 clicks
+ to set up.
+
+
+
+ )}
+
+
+
Available Integrations
+
+
+ Click on the itegration you want to connect. This will let your
+ environment variables flow automatically into selected third-party
+ services.
+
+
+ Note: during an integration with Heroku, for security reasons, it
+ is impossible to maintain end-to-end encryption. In theory, this
+ lets Infisical decrypt yor environment variables. In practice, we
+ can assure you that this will never be done, and it allows us to
+ protect your secrets from bad actors online. The core Infisical
+ service will always stay end-to-end encrypted. With any questions,
+ reach out support@infisical.com.
+
+ To integrate Infisical into your code base and get automatic
+ injection of environmental variables, you should use the
+ following Project ID.
+
+
+ For more guidance, including code snipets for various
+ languages and frameworks, see{" "}
+ {/* eslint-disable-next-line react/jsx-no-target-blank */}
+
+ Infisical Docs.
+
+
+
+
+
+
+
+
+
+
+ Service Tokens
+
+
+ Every service token is specific to you, a certain
+ project and a certain environment within this project.
+
@@ -235,47 +234,42 @@ export default function SettingsBasic() {
*/}
-
-
-
-
- Danger Zone
-
-
- As soon as you delete this project, you will not
- be able to undo it. This will immediately remove
- all the keys. If you still want to do that,
- please enter the name of the project below.
-
-
-
-
-
- Delete Project
-
-
- Note: You can only delete a project in case you
- have more than one.
-
-
-
-
-
-
- );
+
+
+
+
Danger Zone
+
+ As soon as you delete this project, you will not be able to undo
+ it. This will immediately remove all the keys. If you still want
+ to do that, please enter the name of the project below.
+
+
+
+
+
+ Delete Project
+
+
+ Note: You can only delete a project in case you have more than
+ one.
+
+
+
+
+
+
+ );
}
SettingsBasic.requireAuth = true;
diff --git a/frontend/pages/signup.js b/frontend/pages/signup.js
index ce4891d41..e46c6eb20 100644
--- a/frontend/pages/signup.js
+++ b/frontend/pages/signup.js
@@ -1,24 +1,24 @@
-import React, { useState, useRef, useEffect } from "react";
-import { useRouter } from "next/router";
-
+import React, { useEffect, useRef, useState } from "react";
+import dynamic from "next/dynamic";
import Head from "next/head";
import Image from "next/image";
import Link from "next/link";
-import dynamic from "next/dynamic";
+import { useRouter } from "next/router";
+import { faCheck, faWarning, faX } from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+
+import Button from "~/components/basic/buttons/Button";
+import Error from "~/components/basic/Error";
+import InputField from "~/components/basic/InputField";
+import Aes256Gcm from "~/components/utilities/cryptography/aes-256-gcm";
+import issueBackupKey from "~/components/utilities/cryptography/issueBackupKey";
+import attemptLogin from "~/utilities/attemptLogin";
+import passwordCheck from "~/utilities/checks/PasswordCheck";
-import InputField from "../components/basic/InputField";
-import Error from "../components/basic/Error";
-import Button from "../components/basic/buttons/Button";
-import sendVerificationEmail from "./api/auth/SendVerificationEmail";
import checkEmailVerificationCode from "./api/auth/CheckEmailVerificationCode";
import completeAccountInformationSignup from "./api/auth/CompleteAccountInformationSignup";
-import Aes256Gcm from "../components/aes-256-gcm";
-import passwordCheck from "../components/utilities/checks/PasswordCheck";
+import sendVerificationEmail from "./api/auth/SendVerificationEmail";
import getWorkspaces from "./api/workspace/getWorkspaces";
-import attemptLogin from "../components/utilities/attemptLogin";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { faCheck, faX, faWarning } from "@fortawesome/free-solid-svg-icons";
-import issueBackupKey from "../components/utilities/issueBackupKey";
import useTranslation from "next-translate/useTranslation";
import Trans from "next-translate/Trans";
@@ -30,509 +30,489 @@ const client = new jsrp.client();
// The stye for the verification code input
const props = {
- inputStyle: {
- fontFamily: "monospace",
- margin: "4px",
- MozAppearance: "textfield",
- width: "55px",
- borderRadius: "5px",
- fontSize: "24px",
- height: "55px",
- paddingLeft: "7",
- backgroundColor: "#0d1117",
- color: "white",
- border: "1px solid gray",
- textAlign: "center",
- },
+ inputStyle: {
+ fontFamily: "monospace",
+ margin: "4px",
+ MozAppearance: "textfield",
+ width: "55px",
+ borderRadius: "5px",
+ fontSize: "24px",
+ height: "55px",
+ paddingLeft: "7",
+ backgroundColor: "#0d1117",
+ color: "white",
+ border: "1px solid gray",
+ textAlign: "center",
+ },
};
const propsPhone = {
- inputStyle: {
- fontFamily: "monospace",
- margin: "4px",
- MozAppearance: "textfield",
- width: "40px",
- borderRadius: "5px",
- fontSize: "24px",
- height: "40px",
- paddingLeft: "7",
- backgroundColor: "#0d1117",
- color: "white",
- border: "1px solid gray",
- textAlign: "center",
- },
+ inputStyle: {
+ fontFamily: "monospace",
+ margin: "4px",
+ MozAppearance: "textfield",
+ width: "40px",
+ borderRadius: "5px",
+ fontSize: "24px",
+ height: "40px",
+ paddingLeft: "7",
+ backgroundColor: "#0d1117",
+ color: "white",
+ border: "1px solid gray",
+ textAlign: "center",
+ },
};
export default function SignUp() {
- const [email, setEmail] = useState("");
- const [password, setPassword] = useState("");
- const [firstName, setFirstName] = useState("");
- const [lastName, setLastName] = useState("");
- const [code, setCode] = useState("");
- const [codeError, setCodeError] = useState(false);
- const [firstNameError, setFirstNameError] = useState(false);
- const [lastNameError, setLastNameError] = useState(false);
- const [passwordErrorLength, setPasswordErrorLength] = useState(false);
- const [passwordErrorNumber, setPasswordErrorNumber] = useState(false);
- const [passwordErrorUpperCase, setPasswordErrorUpperCase] = useState(false);
- const [passwordErrorLowerCase, setPasswordErrorLowerCase] = useState(false);
- const [passwordErrorSpecialChar, setPasswordErrorSpecialChar] =
- useState(false);
- const [emailError, setEmailError] = useState(false);
- const [emailErrorMessage, setEmailErrorMessage] = useState("");
- const [step, setStep] = useState(1);
- const router = useRouter();
- const [errorLogin, setErrorLogin] = useState(false);
- const [isLoading, setIsLoading] = useState(false);
- const [backupKeyError, setBackupKeyError] = useState(false);
- const [verificationToken, setVerificationToken] = useState();
- const [backupKeyIssued, setBackupKeyIssued] = useState(false);
+ const [email, setEmail] = useState("");
+ const [password, setPassword] = useState("");
+ const [firstName, setFirstName] = useState("");
+ const [lastName, setLastName] = useState("");
+ const [code, setCode] = useState("");
+ const [codeError, setCodeError] = useState(false);
+ const [firstNameError, setFirstNameError] = useState(false);
+ const [lastNameError, setLastNameError] = useState(false);
+ const [passwordErrorLength, setPasswordErrorLength] = useState(false);
+ const [passwordErrorNumber, setPasswordErrorNumber] = useState(false);
+ const [passwordErrorUpperCase, setPasswordErrorUpperCase] = useState(false);
+ const [passwordErrorLowerCase, setPasswordErrorLowerCase] = useState(false);
+ const [passwordErrorSpecialChar, setPasswordErrorSpecialChar] =
+ useState(false);
+ const [emailError, setEmailError] = useState(false);
+ const [emailErrorMessage, setEmailErrorMessage] = useState("");
+ const [step, setStep] = useState(1);
+ const router = useRouter();
+ const [errorLogin, setErrorLogin] = useState(false);
+ const [isLoading, setIsLoading] = useState(false);
+ const [backupKeyError, setBackupKeyError] = useState(false);
+ const [verificationToken, setVerificationToken] = useState();
+ const [backupKeyIssued, setBackupKeyIssued] = useState(false);
- const { t } = useTranslation();
+ const { t } = useTranslation();
- useEffect(async () => {
- let userWorkspace;
- try {
- const userWorkspaces = await getWorkspaces();
- userWorkspace = userWorkspaces[0]._id;
- router.push("auth:/dashboard/" + userWorkspace);
- } catch (error) {
- console.log("auth:Error - Not logged in yet");
- }
- }, []);
+ useEffect(async () => {
+ let userWorkspace;
+ try {
+ const userWorkspaces = await getWorkspaces();
+ userWorkspace = userWorkspaces[0]._id;
+ router.push("/dashboard/" + userWorkspace);
+ } catch (error) {
+ console.log("Error - Not logged in yet");
+ }
+ }, []);
- /**
- * Goes to the following step (out of 3) of the signup process.
- * Step 1 is submitting your email
- * Step 2 is Verifying your email with the code that you received
- * Step 3 is Giving the final info.
- */
- const incrementStep = async () => {
- if (step == 1) {
- setStep(2);
- } else if (step == 2) {
- // Checking if the code matches the email.
- const response = await checkEmailVerificationCode(email, code);
- if (response.status == "200" || code == "111222") {
- setVerificationToken((await response.json()).token);
- setStep(3);
- } else {
- setCodeError(true);
- }
- } else if (step == 3) {
- setStep(4);
- }
- };
+ /**
+ * Goes to the following step (out of 3) of the signup process.
+ * Step 1 is submitting your email
+ * Step 2 is Verifying your email with the code that you received
+ * Step 3 is Giving the final info.
+ */
+ const incrementStep = async () => {
+ if (step == 1) {
+ setStep(2);
+ } else if (step == 2) {
+ // Checking if the code matches the email.
+ const response = await checkEmailVerificationCode(email, code);
+ if (response.status == "200" || code == "111222") {
+ setVerificationToken((await response.json()).token);
+ setStep(3);
+ } else {
+ setCodeError(true);
+ }
+ } else if (step == 3) {
+ setStep(4);
+ }
+ };
- /**
- * Verifies if the entered email "looks" correct
- */
- const emailCheck = () => {
- var emailCheckBool = false;
- if (!email) {
- setEmailError(true);
- setEmailErrorMessage("auth:Please enter your email.");
- emailCheckBool = true;
- } else if (
- !email.includes("auth:@") ||
- !email.includes("auth:.") ||
- !/[a-z]/.test(email)
- ) {
- setEmailError(true);
- setEmailErrorMessage("auth:Please enter a valid email.");
- emailCheckBool = true;
- } else {
- setEmailError(false);
- }
+ /**
+ * Verifies if the entered email "looks" correct
+ */
+ const emailCheck = () => {
+ var emailCheckBool = false;
+ if (!email) {
+ setEmailError(true);
+ setEmailErrorMessage("Please enter your email.");
+ emailCheckBool = true;
+ } else if (
+ !email.includes("@") ||
+ !email.includes(".") ||
+ !/[a-z]/.test(email)
+ ) {
+ setEmailError(true);
+ setEmailErrorMessage("Please enter a valid email.");
+ emailCheckBool = true;
+ } else {
+ setEmailError(false);
+ }
- // If everything is correct, go to the next step
- if (!emailCheckBool) {
- sendVerificationEmail(email);
- incrementStep();
- }
- };
+ // If everything is correct, go to the next step
+ if (!emailCheckBool) {
+ sendVerificationEmail(email);
+ incrementStep();
+ }
+ };
- // Verifies if the imformation that the users entered (name, workspace) is there, and if the password matched the criteria.
- const signupErrorCheck = async () => {
- setIsLoading(true);
- var errorCheck = false;
- if (!firstName) {
- setFirstNameError(true);
- errorCheck = true;
- } else {
- setFirstNameError(false);
- }
- if (!lastName) {
- setLastNameError(true);
- errorCheck = true;
- } else {
- setLastNameError(false);
- }
- errorCheck = passwordCheck(
- password,
- setPasswordErrorLength,
- setPasswordErrorNumber,
- setPasswordErrorLowerCase,
- errorCheck
- );
+ // Verifies if the imformation that the users entered (name, workspace) is there, and if the password matched the criteria.
+ const signupErrorCheck = async () => {
+ setIsLoading(true);
+ var errorCheck = false;
+ if (!firstName) {
+ setFirstNameError(true);
+ errorCheck = true;
+ } else {
+ setFirstNameError(false);
+ }
+ if (!lastName) {
+ setLastNameError(true);
+ errorCheck = true;
+ } else {
+ setLastNameError(false);
+ }
+ errorCheck = passwordCheck(
+ password,
+ setPasswordErrorLength,
+ setPasswordErrorNumber,
+ setPasswordErrorLowerCase,
+ errorCheck
+ );
- if (!errorCheck) {
- // Generate a random pair of a public and a private key
- const pair = nacl.box.keyPair();
- const secretKeyUint8Array = pair.secretKey;
- const publicKeyUint8Array = pair.publicKey;
- const PRIVATE_KEY = nacl.util.encodeBase64(secretKeyUint8Array);
- const PUBLIC_KEY = nacl.util.encodeBase64(publicKeyUint8Array);
+ if (!errorCheck) {
+ // Generate a random pair of a public and a private key
+ const pair = nacl.box.keyPair();
+ const secretKeyUint8Array = pair.secretKey;
+ const publicKeyUint8Array = pair.publicKey;
+ const PRIVATE_KEY = nacl.util.encodeBase64(secretKeyUint8Array);
+ const PUBLIC_KEY = nacl.util.encodeBase64(publicKeyUint8Array);
- const { ciphertext, iv, tag } = Aes256Gcm.encrypt(
- PRIVATE_KEY,
- password
- .slice(0, 32)
- .padStart(
- 32 +
- (password.slice(0, 32).length -
- new Blob([password]).size),
- "0"
- )
- );
- localStorage.setItem("auth:PRIVATE_KEY", PRIVATE_KEY);
+ const { ciphertext, iv, tag } = Aes256Gcm.encrypt(
+ PRIVATE_KEY,
+ password
+ .slice(0, 32)
+ .padStart(
+ 32 + (password.slice(0, 32).length - new Blob([password]).size),
+ "0"
+ )
+ );
+ localStorage.setItem("PRIVATE_KEY", PRIVATE_KEY);
- client.init(
- {
- username: email,
- password: password,
- },
- async () => {
- client.createVerifier(async (err, result) => {
- const response = await completeAccountInformationSignup(
- {
- email,
- firstName,
- lastName,
- organizationName: firstName + "'s organization",
- publicKey: PUBLIC_KEY,
- ciphertext,
- iv,
- tag,
- salt: result.salt,
- verifier: result.verifier,
- token: verificationToken,
- }
- );
+ client.init(
+ {
+ username: email,
+ password: password,
+ },
+ async () => {
+ client.createVerifier(async (err, result) => {
+ const response = await completeAccountInformationSignup({
+ email,
+ firstName,
+ lastName,
+ organizationName: firstName + "'s organization",
+ publicKey: PUBLIC_KEY,
+ ciphertext,
+ iv,
+ tag,
+ salt: result.salt,
+ verifier: result.verifier,
+ token: verificationToken,
+ });
- // if everything works, go the main dashboard page.
- if (!errorCheck && response.status == "200") {
- response = await response.json();
+ // if everything works, go the main dashboard page.
+ if (!errorCheck && response.status == "200") {
+ response = await response.json();
- localStorage.setItem("auth:publicKey", PUBLIC_KEY);
- localStorage.setItem(
- "encryptedPrivateKey",
- ciphertext
- );
- localStorage.setItem("auth:iv", iv);
- localStorage.setItem("auth:tag", tag);
+ localStorage.setItem("publicKey", PUBLIC_KEY);
+ localStorage.setItem("encryptedPrivateKey", ciphertext);
+ localStorage.setItem("iv", iv);
+ localStorage.setItem("tag", tag);
- try {
- await attemptLogin(
- email,
- password,
- setErrorLogin,
- router,
- true,
- false
- );
- incrementStep();
- } catch (error) {
- setIsLoading(false);
- }
- }
- });
- }
- );
- } else {
- setIsLoading(false);
- }
- };
+ try {
+ await attemptLogin(
+ email,
+ password,
+ setErrorLogin,
+ router,
+ true,
+ false
+ );
+ incrementStep();
+ } catch (error) {
+ setIsLoading(false);
+ }
+ }
+ });
+ }
+ );
+ } else {
+ setIsLoading(false);
+ }
+ };
- // Step 1 of the sign up process (enter the email or choose google authentication)
- const step1 = (
-
-
- {t("auth:step1-start")}
-
-
-
-
-
- {t("auth:already-have-account")}
-
-
-
-
-
-
-
- {/*
+ // Step 1 of the sign up process (enter the email or choose google authentication)
+ const step1 = (
+
+
+ {t("auth:step1-start")}
+
+
+
+
+
+ {t("auth:already-have-account")}
+
+
+
+
+
+
+
+ {/*
I do not want to receive emails about Infisical and its products.
*/}
-
-
- By creating an account, you agree to our Terms and have read
- and acknowledged the Privacy Policy.
-
-
-
-
-
-
- );
+
+
+ By creating an account, you agree to our Terms and have read and
+ acknowledged the Privacy Policy.
+
+
+
+
+
+
+ );
- // Step 2 of the signup process (enter the email verification code)
- const step2 = (
-
-
- ),
- email: (
-
- ),
- }}
- values={{ email }}
- />
+ // Step 2 of the signup process (enter the email verification code)
+ const step2 = (
+