mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat(onboarding): backend api for onboarding users
This commit is contained in:
276
backend/package-lock.json
generated
276
backend/package-lock.json
generated
@@ -50,6 +50,7 @@
|
||||
"nanoid": "^3.3.6",
|
||||
"node-cache": "^5.1.2",
|
||||
"nodemailer": "^6.8.0",
|
||||
"ora": "^5.4.1",
|
||||
"passport": "^0.6.0",
|
||||
"passport-github": "^1.1.0",
|
||||
"passport-gitlab2": "^5.0.0",
|
||||
@@ -6574,7 +6575,6 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
@@ -7010,6 +7010,39 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"dependencies": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bl/node_modules/buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "1.20.1",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
|
||||
@@ -7274,7 +7307,6 @@
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
@@ -7380,6 +7412,28 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
||||
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
|
||||
"dependencies": {
|
||||
"restore-cursor": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-spinners": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz",
|
||||
"integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
@@ -7430,7 +7484,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
@@ -7441,8 +7494,7 @@
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"node_modules/color-support": {
|
||||
"version": "1.1.3",
|
||||
@@ -7703,6 +7755,25 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/defaults": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
|
||||
"integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
|
||||
"dependencies": {
|
||||
"clone": "^1.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/defaults/node_modules/clone": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
|
||||
"integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
@@ -8950,7 +9021,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -9400,6 +9470,14 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-interactive": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
|
||||
"integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
@@ -9468,6 +9546,17 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-unicode-supported": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
|
||||
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
@@ -10410,6 +10499,21 @@
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/log-symbols": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
|
||||
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.0",
|
||||
"is-unicode-supported": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
|
||||
@@ -10600,7 +10704,6 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@@ -13835,7 +13938,6 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mimic-fn": "^2.1.0"
|
||||
},
|
||||
@@ -13863,6 +13965,28 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ora": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
|
||||
"integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
|
||||
"dependencies": {
|
||||
"bl": "^4.1.0",
|
||||
"chalk": "^4.1.0",
|
||||
"cli-cursor": "^3.1.0",
|
||||
"cli-spinners": "^2.5.0",
|
||||
"is-interactive": "^1.0.0",
|
||||
"is-unicode-supported": "^0.1.0",
|
||||
"log-symbols": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wcwidth": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-limit": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
||||
@@ -15441,6 +15565,18 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
|
||||
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
|
||||
"dependencies": {
|
||||
"onetime": "^5.1.0",
|
||||
"signal-exit": "^3.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
@@ -16088,7 +16224,6 @@
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
@@ -16705,6 +16840,14 @@
|
||||
"makeerror": "1.0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/wcwidth": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
|
||||
"integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
|
||||
"dependencies": {
|
||||
"defaults": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||
@@ -22216,7 +22359,6 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
@@ -22549,6 +22691,27 @@
|
||||
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||
"dev": true
|
||||
},
|
||||
"bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"requires": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"requires": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.20.1",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
|
||||
@@ -22741,7 +22904,6 @@
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
@@ -22811,6 +22973,19 @@
|
||||
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
|
||||
"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="
|
||||
},
|
||||
"cli-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
||||
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
|
||||
"requires": {
|
||||
"restore-cursor": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"cli-spinners": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz",
|
||||
"integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ=="
|
||||
},
|
||||
"cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
@@ -22848,7 +23023,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
@@ -22856,8 +23030,7 @@
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"color-support": {
|
||||
"version": "1.1.3",
|
||||
@@ -23057,6 +23230,21 @@
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="
|
||||
},
|
||||
"defaults": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
|
||||
"integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
|
||||
"requires": {
|
||||
"clone": "^1.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"clone": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
|
||||
"integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
@@ -23984,8 +24172,7 @@
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
},
|
||||
"has-proto": {
|
||||
"version": "1.0.1",
|
||||
@@ -24308,6 +24495,11 @@
|
||||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"is-interactive": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
|
||||
"integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="
|
||||
},
|
||||
"is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
@@ -24349,6 +24541,11 @@
|
||||
"which-typed-array": "^1.1.11"
|
||||
}
|
||||
},
|
||||
"is-unicode-supported": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
|
||||
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
@@ -25091,6 +25288,15 @@
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||
"dev": true
|
||||
},
|
||||
"log-symbols": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
|
||||
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
"is-unicode-supported": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"long": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
|
||||
@@ -25236,8 +25442,7 @@
|
||||
"mimic-fn": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.1.2",
|
||||
@@ -27519,7 +27724,6 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mimic-fn": "^2.1.0"
|
||||
}
|
||||
@@ -27538,6 +27742,22 @@
|
||||
"type-check": "^0.4.0"
|
||||
}
|
||||
},
|
||||
"ora": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
|
||||
"integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
|
||||
"requires": {
|
||||
"bl": "^4.1.0",
|
||||
"chalk": "^4.1.0",
|
||||
"cli-cursor": "^3.1.0",
|
||||
"cli-spinners": "^2.5.0",
|
||||
"is-interactive": "^1.0.0",
|
||||
"is-unicode-supported": "^0.1.0",
|
||||
"log-symbols": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wcwidth": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
||||
@@ -28751,6 +28971,15 @@
|
||||
"integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==",
|
||||
"dev": true
|
||||
},
|
||||
"restore-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
|
||||
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
|
||||
"requires": {
|
||||
"onetime": "^5.1.0",
|
||||
"signal-exit": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
@@ -29249,7 +29478,6 @@
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
@@ -29698,6 +29926,14 @@
|
||||
"makeerror": "1.0.12"
|
||||
}
|
||||
},
|
||||
"wcwidth": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
|
||||
"integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
|
||||
"requires": {
|
||||
"defaults": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||
|
||||
@@ -41,13 +41,14 @@
|
||||
"nanoid": "^3.3.6",
|
||||
"node-cache": "^5.1.2",
|
||||
"nodemailer": "^6.8.0",
|
||||
"ora": "^5.4.1",
|
||||
"passport": "^0.6.0",
|
||||
"passport-github": "^1.1.0",
|
||||
"passport-gitlab2": "^5.0.0",
|
||||
"passport-google-oauth20": "^2.0.0",
|
||||
"pg": "^8.11.3",
|
||||
"pino": "^8.16.1",
|
||||
"pino-http": "^8.5.1",
|
||||
"pg": "^8.11.3",
|
||||
"posthog-node": "^2.6.0",
|
||||
"probot": "^12.3.1",
|
||||
"query-string": "^7.1.3",
|
||||
|
||||
43
backend/src/bootstrap.ts
Normal file
43
backend/src/bootstrap.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import ora from "ora";
|
||||
import nodemailer from "nodemailer";
|
||||
import { getSmtpHost, getSmtpPort } from "./config";
|
||||
import { logger } from "./utils/logging";
|
||||
import mongoose from "mongoose";
|
||||
import { redisClient } from "./services/RedisService";
|
||||
|
||||
type BootstrapOpt = {
|
||||
transporter: nodemailer.Transporter;
|
||||
};
|
||||
|
||||
export const bootstrap = async ({ transporter }: BootstrapOpt) => {
|
||||
const spinner = ora().start();
|
||||
spinner.info("Checking configurations...");
|
||||
spinner.info("Testing smtp connection");
|
||||
|
||||
await transporter
|
||||
.verify()
|
||||
.then(async () => {
|
||||
spinner.succeed("SMTP successfully connected");
|
||||
})
|
||||
.catch(async (err) => {
|
||||
spinner.fail(`SMTP - Failed to connect to ${await getSmtpHost()}:${await getSmtpPort()}`);
|
||||
logger.error(err);
|
||||
});
|
||||
|
||||
spinner.info("Testing mongodb connection");
|
||||
if (mongoose.connection.readyState !== mongoose.ConnectionStates.connected) {
|
||||
spinner.fail("Mongo DB - Failed to connect");
|
||||
} else {
|
||||
spinner.succeed("Mongodb successfully connected");
|
||||
}
|
||||
|
||||
spinner.info("Testing redis connection");
|
||||
const redisPing = await redisClient?.ping();
|
||||
if (!redisPing) {
|
||||
spinner.fail("Redis - Failed to connect");
|
||||
} else {
|
||||
spinner.succeed("Redis successfully connected");
|
||||
}
|
||||
|
||||
spinner.stop();
|
||||
};
|
||||
24
backend/src/config/serverConfig.ts
Normal file
24
backend/src/config/serverConfig.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { IServerConfig, ServerConfig } from "../models/serverConfig";
|
||||
|
||||
let serverConfig: IServerConfig;
|
||||
|
||||
export const serverConfigInit = async () => {
|
||||
const cfg = await ServerConfig.findOne({});
|
||||
if (!cfg) {
|
||||
const cfg = new ServerConfig();
|
||||
await cfg.save();
|
||||
serverConfig = cfg;
|
||||
} else {
|
||||
serverConfig = cfg;
|
||||
}
|
||||
return serverConfig;
|
||||
};
|
||||
|
||||
export const getServerConfig = () => serverConfig;
|
||||
|
||||
export const updateServerConfig = async (data: Partial<IServerConfig>) => {
|
||||
const cfg = await ServerConfig.findByIdAndUpdate(serverConfig._id, data, { new: true });
|
||||
if (!cfg) throw new Error("Failed to update server config");
|
||||
serverConfig = cfg;
|
||||
return serverConfig;
|
||||
};
|
||||
87
backend/src/controllers/v1/adminController.ts
Normal file
87
backend/src/controllers/v1/adminController.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { Request, Response } from "express";
|
||||
import { getHttpsEnabled } from "../../config";
|
||||
import { getServerConfig, updateServerConfig as setServerConfig } from "../../config/serverConfig";
|
||||
import { initializeDefaultOrg, issueAuthTokens } from "../../helpers";
|
||||
import { validateRequest } from "../../helpers/validation";
|
||||
import { User } from "../../models";
|
||||
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
|
||||
import * as reqValidator from "../../validation/admin";
|
||||
|
||||
export const getServerConfigInfo = (_req: Request, res: Response) => {
|
||||
const config = getServerConfig();
|
||||
return res.send({ config });
|
||||
};
|
||||
|
||||
export const updateServerConfig = async (req: Request, res: Response) => {
|
||||
const {
|
||||
body: { allowSignUp }
|
||||
} = await validateRequest(reqValidator.UpdateServerConfigV1, req);
|
||||
const config = await setServerConfig({ allowSignUp });
|
||||
return res.send({ config });
|
||||
};
|
||||
|
||||
export const adminSignUp = async (req: Request, res: Response) => {
|
||||
const cfg = getServerConfig();
|
||||
if (cfg.initialized) throw UnauthorizedRequestError({ message: "Admin has been created" });
|
||||
const {
|
||||
body: {
|
||||
email,
|
||||
publicKey,
|
||||
salt,
|
||||
lastName,
|
||||
verifier,
|
||||
firstName,
|
||||
protectedKey,
|
||||
protectedKeyIV,
|
||||
protectedKeyTag,
|
||||
encryptedPrivateKey,
|
||||
encryptedPrivateKeyIV,
|
||||
encryptedPrivateKeyTag
|
||||
}
|
||||
} = await validateRequest(reqValidator.SignupV1, req);
|
||||
let user = await User.findOne({ email });
|
||||
if (user) throw BadRequestError({ message: "User already exist" });
|
||||
user = new User({
|
||||
email,
|
||||
firstName,
|
||||
lastName,
|
||||
encryptionVersion: 2,
|
||||
protectedKey,
|
||||
protectedKeyIV,
|
||||
protectedKeyTag,
|
||||
publicKey,
|
||||
encryptedPrivateKey,
|
||||
iv: encryptedPrivateKeyIV,
|
||||
tag: encryptedPrivateKeyTag,
|
||||
salt,
|
||||
verifier,
|
||||
superAdmin: true
|
||||
});
|
||||
await user.save();
|
||||
await initializeDefaultOrg({ organizationName: "Admin Org", user });
|
||||
|
||||
await setServerConfig({ initialized: true });
|
||||
|
||||
// issue tokens
|
||||
const tokens = await issueAuthTokens({
|
||||
userId: user._id,
|
||||
ip: req.realIP,
|
||||
userAgent: req.headers["user-agent"] ?? ""
|
||||
});
|
||||
|
||||
const token = tokens.token;
|
||||
|
||||
// store (refresh) token in httpOnly cookie
|
||||
res.cookie("jid", tokens.refreshToken, {
|
||||
httpOnly: true,
|
||||
path: "/",
|
||||
sameSite: "strict",
|
||||
secure: await getHttpsEnabled()
|
||||
});
|
||||
|
||||
return res.status(200).send({
|
||||
message: "Successfully set up admin account",
|
||||
user,
|
||||
token
|
||||
});
|
||||
};
|
||||
@@ -16,6 +16,8 @@ import * as workspaceController from "./workspaceController";
|
||||
import * as secretScanningController from "./secretScanningController";
|
||||
import * as webhookController from "./webhookController";
|
||||
import * as secretImpsController from "./secretImpsController";
|
||||
import * as adminController from "./adminController";
|
||||
|
||||
export {
|
||||
authController,
|
||||
botController,
|
||||
@@ -34,5 +36,6 @@ export {
|
||||
workspaceController,
|
||||
secretScanningController,
|
||||
webhookController,
|
||||
secretImpsController
|
||||
secretImpsController,
|
||||
adminController
|
||||
};
|
||||
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
import { apiKeyData as v3apiKeyDataRouter } from "./ee/routes/v3";
|
||||
import { serviceTokenData as v3ServiceTokenDataRouter } from "./ee/routes/v3";
|
||||
import {
|
||||
admin as v1AdminRouter,
|
||||
auth as v1AuthRouter,
|
||||
bot as v1BotRouter,
|
||||
integrationAuth as v1IntegrationAuthRouter,
|
||||
@@ -94,6 +95,7 @@ import { syncSecretsToThirdPartyServices } from "./queues/integrations/syncSecre
|
||||
import { githubPushEventSecretScan } from "./queues/secret-scanning/githubScanPushEvent";
|
||||
const SmeeClient = require("smee-client"); // eslint-disable-line
|
||||
import path from "path";
|
||||
import { serverConfigInit } from "./config/serverConfig";
|
||||
|
||||
let handler: null | any = null;
|
||||
|
||||
@@ -101,6 +103,7 @@ const main = async () => {
|
||||
const port = await getPort();
|
||||
|
||||
await setup();
|
||||
const serverCfg = await serverConfigInit();
|
||||
|
||||
await EELicenseService.initGlobalFeatureSet();
|
||||
|
||||
@@ -203,6 +206,7 @@ const main = async () => {
|
||||
// v1 routes
|
||||
app.use("/api/v1/signup", v1SignupRouter);
|
||||
app.use("/api/v1/auth", v1AuthRouter);
|
||||
app.use("/api/v1/admin", v1AdminRouter);
|
||||
app.use("/api/v1/bot", v1BotRouter);
|
||||
app.use("/api/v1/user", v1UserRouter);
|
||||
app.use("/api/v1/user-action", v1UserActionRouter);
|
||||
@@ -271,7 +275,22 @@ const main = async () => {
|
||||
app.use(requestErrorHandler);
|
||||
|
||||
const server = app.listen(port, async () => {
|
||||
logger.info(`Server started listening at port ${port}`);
|
||||
if (!serverCfg.initialized) {
|
||||
logger.info(`Welcome to Infisical
|
||||
|
||||
Create your Infisical administrator account at:
|
||||
http://localhost:${port}/admin/signup
|
||||
`);
|
||||
} else {
|
||||
logger.info(`Welcome back!
|
||||
|
||||
To access Infisical Administrator Panel open
|
||||
http://localhost:${port}/admin
|
||||
|
||||
To access Infisical server
|
||||
http://localhost:${port}
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
// await createTestUserForDevelopment();
|
||||
|
||||
@@ -7,17 +7,21 @@ import requireSecretAuth from "./requireSecretAuth";
|
||||
import requireSecretsAuth from "./requireSecretsAuth";
|
||||
import requireBlindIndicesEnabled from "./requireBlindIndicesEnabled";
|
||||
import requireE2EEOff from "./requireE2EEOff";
|
||||
import { requireSuperAdminAccess } from "./requireSuperAdminAccess";
|
||||
import validateRequest from "./validateRequest";
|
||||
import { disableSignUpByServerCfg } from "./serverAdmin";
|
||||
|
||||
export {
|
||||
requireAuth,
|
||||
requireMfaAuth,
|
||||
requireSignupAuth,
|
||||
requireWorkspaceAuth,
|
||||
requireServiceTokenAuth,
|
||||
requireSecretAuth,
|
||||
requireSecretsAuth,
|
||||
requireBlindIndicesEnabled,
|
||||
requireE2EEOff,
|
||||
validateRequest,
|
||||
requireAuth,
|
||||
requireMfaAuth,
|
||||
requireSignupAuth,
|
||||
requireWorkspaceAuth,
|
||||
requireServiceTokenAuth,
|
||||
requireSecretAuth,
|
||||
requireSecretsAuth,
|
||||
requireBlindIndicesEnabled,
|
||||
requireE2EEOff,
|
||||
validateRequest,
|
||||
requireSuperAdminAccess,
|
||||
disableSignUpByServerCfg
|
||||
};
|
||||
|
||||
8
backend/src/middleware/requireSuperAdminAccess.ts
Normal file
8
backend/src/middleware/requireSuperAdminAccess.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import { UnauthorizedRequestError } from "../utils/errors";
|
||||
|
||||
export const requireSuperAdminAccess = (req: Request, _res: Response, next: NextFunction) => {
|
||||
const isSuperAdmin = req.user.superAdmin;
|
||||
if (!isSuperAdmin) throw UnauthorizedRequestError({ message: "Requires superadmin access" });
|
||||
return next();
|
||||
};
|
||||
9
backend/src/middleware/serverAdmin.ts
Normal file
9
backend/src/middleware/serverAdmin.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import { getServerConfig } from "../config/serverConfig";
|
||||
import { BadRequestError } from "../utils/errors";
|
||||
|
||||
export const disableSignUpByServerCfg = (_req: Request, _res: Response, next: NextFunction) => {
|
||||
const cfg = getServerConfig();
|
||||
if (!cfg.allowSignUp) throw BadRequestError({ message: "Signup are disabled" });
|
||||
return next();
|
||||
};
|
||||
25
backend/src/models/serverConfig.ts
Normal file
25
backend/src/models/serverConfig.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Schema, Types, model } from "mongoose";
|
||||
|
||||
export interface IServerConfig {
|
||||
_id: Types.ObjectId;
|
||||
initialized: boolean;
|
||||
allowSignUp: boolean;
|
||||
}
|
||||
|
||||
const serverConfigSchema = new Schema<IServerConfig>(
|
||||
{
|
||||
initialized: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
allowSignUp: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
{
|
||||
timestamps: true
|
||||
}
|
||||
);
|
||||
|
||||
export const ServerConfig = model<IServerConfig>("ServerConfig", serverConfigSchema);
|
||||
@@ -1,125 +1,141 @@
|
||||
import { Document, Schema, Types, model } from "mongoose";
|
||||
|
||||
export enum AuthMethod {
|
||||
EMAIL = "email",
|
||||
GOOGLE = "google",
|
||||
GITHUB = "github",
|
||||
GITLAB = "gitlab",
|
||||
OKTA_SAML = "okta-saml",
|
||||
AZURE_SAML = "azure-saml",
|
||||
JUMPCLOUD_SAML = "jumpcloud-saml",
|
||||
EMAIL = "email",
|
||||
GOOGLE = "google",
|
||||
GITHUB = "github",
|
||||
GITLAB = "gitlab",
|
||||
OKTA_SAML = "okta-saml",
|
||||
AZURE_SAML = "azure-saml",
|
||||
JUMPCLOUD_SAML = "jumpcloud-saml"
|
||||
}
|
||||
|
||||
export interface IUser extends Document {
|
||||
_id: Types.ObjectId;
|
||||
authProvider?: AuthMethod;
|
||||
authMethods: AuthMethod[];
|
||||
email: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
encryptionVersion: number;
|
||||
protectedKey: string;
|
||||
protectedKeyIV: string;
|
||||
protectedKeyTag: string;
|
||||
publicKey?: string;
|
||||
encryptedPrivateKey?: string;
|
||||
iv?: string;
|
||||
tag?: string;
|
||||
salt?: string;
|
||||
verifier?: string;
|
||||
isMfaEnabled: boolean;
|
||||
mfaMethods: boolean;
|
||||
devices: {
|
||||
ip: string;
|
||||
userAgent: string;
|
||||
}[];
|
||||
_id: Types.ObjectId;
|
||||
authProvider?: AuthMethod;
|
||||
authMethods: AuthMethod[];
|
||||
email: string;
|
||||
superAdmin?: boolean;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
encryptionVersion: number;
|
||||
protectedKey: string;
|
||||
protectedKeyIV: string;
|
||||
protectedKeyTag: string;
|
||||
publicKey?: string;
|
||||
encryptedPrivateKey?: string;
|
||||
iv?: string;
|
||||
tag?: string;
|
||||
salt?: string;
|
||||
verifier?: string;
|
||||
isMfaEnabled: boolean;
|
||||
mfaMethods: boolean;
|
||||
devices: {
|
||||
ip: string;
|
||||
userAgent: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
const userSchema = new Schema<IUser>(
|
||||
{
|
||||
authProvider: { // TODO field: deprecate
|
||||
type: String,
|
||||
enum: AuthMethod,
|
||||
},
|
||||
authMethods: {
|
||||
type: [{
|
||||
type: String,
|
||||
enum: AuthMethod,
|
||||
}],
|
||||
default: [AuthMethod.EMAIL],
|
||||
required: true
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true,
|
||||
},
|
||||
firstName: {
|
||||
type: String,
|
||||
},
|
||||
lastName: {
|
||||
type: String,
|
||||
},
|
||||
encryptionVersion: {
|
||||
type: Number,
|
||||
select: false,
|
||||
default: 1, // to resolve backward-compatibility issues
|
||||
},
|
||||
protectedKey: { // introduced as part of encryption version 2
|
||||
type: String,
|
||||
select: false,
|
||||
},
|
||||
protectedKeyIV: { // introduced as part of encryption version 2
|
||||
type: String,
|
||||
select: false,
|
||||
},
|
||||
protectedKeyTag: { // introduced as part of encryption version 2
|
||||
type: String,
|
||||
select: false,
|
||||
},
|
||||
publicKey: {
|
||||
type: String,
|
||||
select: false,
|
||||
},
|
||||
encryptedPrivateKey: {
|
||||
type: String,
|
||||
select: false,
|
||||
},
|
||||
iv: { // iv of [encryptedPrivateKey]
|
||||
type: String,
|
||||
select: false,
|
||||
},
|
||||
tag: { // tag of [encryptedPrivateKey]
|
||||
type: String,
|
||||
select: false,
|
||||
},
|
||||
salt: {
|
||||
type: String,
|
||||
select: false,
|
||||
},
|
||||
verifier: {
|
||||
type: String,
|
||||
select: false,
|
||||
},
|
||||
isMfaEnabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
mfaMethods: [{
|
||||
type: String,
|
||||
}],
|
||||
devices: {
|
||||
type: [{
|
||||
ip: String,
|
||||
userAgent: String,
|
||||
}],
|
||||
default: [],
|
||||
select: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
timestamps: true,
|
||||
}
|
||||
{
|
||||
authProvider: {
|
||||
// TODO field: deprecate
|
||||
type: String,
|
||||
enum: AuthMethod
|
||||
},
|
||||
authMethods: {
|
||||
type: [
|
||||
{
|
||||
type: String,
|
||||
enum: AuthMethod
|
||||
}
|
||||
],
|
||||
default: [AuthMethod.EMAIL],
|
||||
required: true
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true
|
||||
},
|
||||
firstName: {
|
||||
type: String
|
||||
},
|
||||
lastName: {
|
||||
type: String
|
||||
},
|
||||
encryptionVersion: {
|
||||
type: Number,
|
||||
select: false,
|
||||
default: 1 // to resolve backward-compatibility issues
|
||||
},
|
||||
protectedKey: {
|
||||
// introduced as part of encryption version 2
|
||||
type: String,
|
||||
select: false
|
||||
},
|
||||
protectedKeyIV: {
|
||||
// introduced as part of encryption version 2
|
||||
type: String,
|
||||
select: false
|
||||
},
|
||||
protectedKeyTag: {
|
||||
// introduced as part of encryption version 2
|
||||
type: String,
|
||||
select: false
|
||||
},
|
||||
publicKey: {
|
||||
type: String,
|
||||
select: false
|
||||
},
|
||||
encryptedPrivateKey: {
|
||||
type: String,
|
||||
select: false
|
||||
},
|
||||
superAdmin: {
|
||||
type: Boolean
|
||||
},
|
||||
iv: {
|
||||
// iv of [encryptedPrivateKey]
|
||||
type: String,
|
||||
select: false
|
||||
},
|
||||
tag: {
|
||||
// tag of [encryptedPrivateKey]
|
||||
type: String,
|
||||
select: false
|
||||
},
|
||||
salt: {
|
||||
type: String,
|
||||
select: false
|
||||
},
|
||||
verifier: {
|
||||
type: String,
|
||||
select: false
|
||||
},
|
||||
isMfaEnabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
mfaMethods: [
|
||||
{
|
||||
type: String
|
||||
}
|
||||
],
|
||||
devices: {
|
||||
type: [
|
||||
{
|
||||
ip: String,
|
||||
userAgent: String
|
||||
}
|
||||
],
|
||||
default: [],
|
||||
select: false
|
||||
}
|
||||
},
|
||||
{
|
||||
timestamps: true
|
||||
}
|
||||
);
|
||||
|
||||
export const User = model<IUser>("User", userSchema);
|
||||
export const User = model<IUser>("User", userSchema);
|
||||
|
||||
20
backend/src/routes/v1/admin.ts
Normal file
20
backend/src/routes/v1/admin.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import express from "express";
|
||||
import { adminController } from "../../controllers/v1";
|
||||
const router = express.Router();
|
||||
import { requireAuth, requireSuperAdminAccess } from "../../middleware";
|
||||
import { AuthMode } from "../../variables";
|
||||
|
||||
router.get("/config", adminController.getServerConfigInfo);
|
||||
|
||||
router.post("/signup", adminController.adminSignUp);
|
||||
|
||||
router.patch(
|
||||
"/config",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY]
|
||||
}),
|
||||
requireSuperAdminAccess,
|
||||
adminController.updateServerConfig
|
||||
);
|
||||
|
||||
export default router;
|
||||
@@ -18,6 +18,7 @@ import integrationAuth from "./integrationAuth";
|
||||
import secretsFolder from "./secretsFolder";
|
||||
import webhooks from "./webhook";
|
||||
import secretImps from "./secretImps";
|
||||
import admin from "./admin";
|
||||
|
||||
export {
|
||||
signup,
|
||||
@@ -39,5 +40,6 @@ export {
|
||||
secretsFolder,
|
||||
webhooks,
|
||||
secretImps,
|
||||
sso
|
||||
sso,
|
||||
admin
|
||||
};
|
||||
|
||||
@@ -2,18 +2,21 @@ import express from "express";
|
||||
const router = express.Router();
|
||||
import { signupController } from "../../controllers/v1";
|
||||
import { authLimiter } from "../../helpers/rateLimiter";
|
||||
import { disableSignUpByServerCfg } from "../../middleware";
|
||||
|
||||
// TODO: consider moving to users/v3/signup
|
||||
|
||||
router.post(
|
||||
// TODO endpoint: consider moving to v3/users/signup/mail
|
||||
"/email/signup",
|
||||
disableSignUpByServerCfg,
|
||||
authLimiter,
|
||||
signupController.beginEmailSignup
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/email/verify", // TODO endpoint: consider moving to v3/users/signup/verify
|
||||
disableSignUpByServerCfg,
|
||||
authLimiter,
|
||||
signupController.verifyEmailSignup
|
||||
);
|
||||
|
||||
@@ -1,49 +1,51 @@
|
||||
import express from "express";
|
||||
const router = express.Router();
|
||||
import { body } from "express-validator";
|
||||
import { requireSignupAuth, validateRequest } from "../../middleware";
|
||||
import { disableSignUpByServerCfg, requireSignupAuth, validateRequest } from "../../middleware";
|
||||
import { signupController } from "../../controllers/v2";
|
||||
import { authLimiter } from "../../helpers/rateLimiter";
|
||||
|
||||
router.post(
|
||||
"/complete-account/signup", // TODO endpoint: deprecate (moved to v3/signup/complete/account-signup)
|
||||
authLimiter,
|
||||
requireSignupAuth,
|
||||
body("email").exists().isString().trim().notEmpty().isEmail(),
|
||||
body("firstName").exists().isString().trim().notEmpty(),
|
||||
body("lastName").exists().isString().trim().notEmpty(),
|
||||
body("protectedKey").exists().isString().trim().notEmpty(),
|
||||
body("protectedKeyIV").exists().isString().trim().notEmpty(),
|
||||
body("protectedKeyTag").exists().isString().trim().notEmpty(),
|
||||
body("publicKey").exists().isString().trim().notEmpty(),
|
||||
body("encryptedPrivateKey").exists().isString().trim().notEmpty(),
|
||||
body("encryptedPrivateKeyIV").exists().isString().trim().notEmpty(),
|
||||
body("encryptedPrivateKeyTag").exists().isString().trim().notEmpty(),
|
||||
body("salt").exists().isString().trim().notEmpty(),
|
||||
body("verifier").exists().isString().trim().notEmpty(),
|
||||
body("organizationName").exists().isString().trim().notEmpty(),
|
||||
validateRequest,
|
||||
signupController.completeAccountSignup
|
||||
"/complete-account/signup", // TODO endpoint: deprecate (moved to v3/signup/complete/account-signup),
|
||||
disableSignUpByServerCfg,
|
||||
authLimiter,
|
||||
requireSignupAuth,
|
||||
body("email").exists().isString().trim().notEmpty().isEmail(),
|
||||
body("firstName").exists().isString().trim().notEmpty(),
|
||||
body("lastName").exists().isString().trim().notEmpty(),
|
||||
body("protectedKey").exists().isString().trim().notEmpty(),
|
||||
body("protectedKeyIV").exists().isString().trim().notEmpty(),
|
||||
body("protectedKeyTag").exists().isString().trim().notEmpty(),
|
||||
body("publicKey").exists().isString().trim().notEmpty(),
|
||||
body("encryptedPrivateKey").exists().isString().trim().notEmpty(),
|
||||
body("encryptedPrivateKeyIV").exists().isString().trim().notEmpty(),
|
||||
body("encryptedPrivateKeyTag").exists().isString().trim().notEmpty(),
|
||||
body("salt").exists().isString().trim().notEmpty(),
|
||||
body("verifier").exists().isString().trim().notEmpty(),
|
||||
body("organizationName").exists().isString().trim().notEmpty(),
|
||||
validateRequest,
|
||||
signupController.completeAccountSignup
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/complete-account/invite", // TODO: consider moving to v3/users/new/complete-account/invite
|
||||
authLimiter,
|
||||
requireSignupAuth,
|
||||
body("email").exists().isString().trim().notEmpty().isEmail(),
|
||||
body("firstName").exists().isString().trim().notEmpty(),
|
||||
body("lastName").exists().isString().trim().notEmpty(),
|
||||
body("protectedKey").exists().isString().trim().notEmpty(),
|
||||
body("protectedKeyIV").exists().isString().trim().notEmpty(),
|
||||
body("protectedKeyTag").exists().isString().trim().notEmpty(),
|
||||
body("publicKey").exists().trim().notEmpty(),
|
||||
body("encryptedPrivateKey").exists().isString().trim().notEmpty(),
|
||||
body("encryptedPrivateKeyIV").exists().isString().trim().notEmpty(),
|
||||
body("encryptedPrivateKeyTag").exists().isString().trim().notEmpty(),
|
||||
body("salt").exists().isString().trim().notEmpty(),
|
||||
body("verifier").exists().isString().trim().notEmpty(),
|
||||
validateRequest,
|
||||
signupController.completeAccountInvite
|
||||
"/complete-account/invite", // TODO: consider moving to v3/users/new/complete-account/invite
|
||||
disableSignUpByServerCfg,
|
||||
authLimiter,
|
||||
requireSignupAuth,
|
||||
body("email").exists().isString().trim().notEmpty().isEmail(),
|
||||
body("firstName").exists().isString().trim().notEmpty(),
|
||||
body("lastName").exists().isString().trim().notEmpty(),
|
||||
body("protectedKey").exists().isString().trim().notEmpty(),
|
||||
body("protectedKeyIV").exists().isString().trim().notEmpty(),
|
||||
body("protectedKeyTag").exists().isString().trim().notEmpty(),
|
||||
body("publicKey").exists().trim().notEmpty(),
|
||||
body("encryptedPrivateKey").exists().isString().trim().notEmpty(),
|
||||
body("encryptedPrivateKeyIV").exists().isString().trim().notEmpty(),
|
||||
body("encryptedPrivateKeyTag").exists().isString().trim().notEmpty(),
|
||||
body("salt").exists().isString().trim().notEmpty(),
|
||||
body("verifier").exists().isString().trim().notEmpty(),
|
||||
validateRequest,
|
||||
signupController.completeAccountInvite
|
||||
);
|
||||
|
||||
export default router;
|
||||
export default router;
|
||||
|
||||
@@ -2,10 +2,11 @@ import express from "express";
|
||||
const router = express.Router();
|
||||
import { signupController } from "../../controllers/v3";
|
||||
import { authLimiter } from "../../helpers/rateLimiter";
|
||||
import { validateRequest } from "../../middleware";
|
||||
import { disableSignUpByServerCfg, validateRequest } from "../../middleware";
|
||||
|
||||
router.post(
|
||||
"/complete-account/signup", // TODO: consider moving endpoint to v3/users/new/complete-account/signup
|
||||
disableSignUpByServerCfg,
|
||||
authLimiter,
|
||||
validateRequest,
|
||||
signupController.completeAccountSignup
|
||||
|
||||
@@ -8,30 +8,28 @@ import {
|
||||
SMTP_HOST_ZOHOMAIL
|
||||
} from "../variables";
|
||||
import SMTPConnection from "nodemailer/lib/smtp-connection";
|
||||
import * as Sentry from "@sentry/node";
|
||||
import {
|
||||
getSmtpHost,
|
||||
getSmtpPassword,
|
||||
getSmtpPort,
|
||||
getSmtpSecure,
|
||||
getSmtpUsername,
|
||||
getSmtpUsername
|
||||
} from "../config";
|
||||
import { logger } from "../utils/logging";
|
||||
|
||||
export const initSmtp = async () => {
|
||||
const mailOpts: SMTPConnection.Options = {
|
||||
host: await getSmtpHost(),
|
||||
port: await getSmtpPort(),
|
||||
port: await getSmtpPort()
|
||||
};
|
||||
|
||||
if ((await getSmtpUsername()) && (await getSmtpPassword())) {
|
||||
mailOpts.auth = {
|
||||
user: await getSmtpUsername(),
|
||||
pass: await getSmtpPassword(),
|
||||
pass: await getSmtpPassword()
|
||||
};
|
||||
}
|
||||
|
||||
if ((await getSmtpSecure()) ? (await getSmtpSecure()) : false) {
|
||||
if ((await getSmtpSecure()) ? await getSmtpSecure() : false) {
|
||||
switch (await getSmtpHost()) {
|
||||
case SMTP_HOST_SENDGRID:
|
||||
mailOpts.requireTLS = true;
|
||||
@@ -39,38 +37,38 @@ export const initSmtp = async () => {
|
||||
case SMTP_HOST_MAILGUN:
|
||||
mailOpts.requireTLS = true;
|
||||
mailOpts.tls = {
|
||||
ciphers: "TLSv1.2",
|
||||
}
|
||||
ciphers: "TLSv1.2"
|
||||
};
|
||||
break;
|
||||
case SMTP_HOST_SOCKETLABS:
|
||||
mailOpts.requireTLS = true;
|
||||
mailOpts.tls = {
|
||||
ciphers: "TLSv1.2",
|
||||
}
|
||||
ciphers: "TLSv1.2"
|
||||
};
|
||||
break;
|
||||
case SMTP_HOST_ZOHOMAIL:
|
||||
mailOpts.requireTLS = true;
|
||||
mailOpts.tls = {
|
||||
ciphers: "TLSv1.2",
|
||||
}
|
||||
ciphers: "TLSv1.2"
|
||||
};
|
||||
break;
|
||||
case SMTP_HOST_GMAIL:
|
||||
mailOpts.requireTLS = true;
|
||||
mailOpts.tls = {
|
||||
ciphers: "TLSv1.2",
|
||||
}
|
||||
ciphers: "TLSv1.2"
|
||||
};
|
||||
break;
|
||||
case SMTP_HOST_OFFICE365:
|
||||
mailOpts.requireTLS = true;
|
||||
mailOpts.tls = {
|
||||
ciphers: "TLSv1.2"
|
||||
}
|
||||
};
|
||||
break;
|
||||
default:
|
||||
if ((await getSmtpHost()).includes("amazonaws.com")) {
|
||||
mailOpts.tls = {
|
||||
ciphers: "TLSv1.2",
|
||||
}
|
||||
ciphers: "TLSv1.2"
|
||||
};
|
||||
} else {
|
||||
mailOpts.secure = true;
|
||||
}
|
||||
@@ -79,20 +77,6 @@ export const initSmtp = async () => {
|
||||
}
|
||||
|
||||
const transporter = nodemailer.createTransport(mailOpts);
|
||||
transporter
|
||||
.verify()
|
||||
.then(async () => {
|
||||
Sentry.setUser(null);
|
||||
Sentry.captureMessage("SMTP - Successfully connected");
|
||||
logger.info("SMTP - Successfully connected");
|
||||
})
|
||||
.catch(async (err) => {
|
||||
Sentry.setUser(null);
|
||||
Sentry.captureException(
|
||||
`SMTP - Failed to connect to ${await getSmtpHost()}:${await getSmtpPort()} \n\t${err}`
|
||||
);
|
||||
logger.error(err, `SMTP - Failed to connect to ${await getSmtpHost()}:${await getSmtpPort()}`);
|
||||
});
|
||||
|
||||
return transporter;
|
||||
};
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
initializeSamlStrategy
|
||||
} from "../authn/passport";
|
||||
import { logger } from "../logging";
|
||||
import { bootstrap } from "../../bootstrap";
|
||||
|
||||
/**
|
||||
* Prepare Infisical upon startup. This includes tasks like:
|
||||
@@ -55,14 +56,15 @@ export const setup = async () => {
|
||||
await TelemetryService.logTelemetryMessage();
|
||||
|
||||
// initializing SMTP configuration
|
||||
setTransporter(await initSmtp());
|
||||
const transporter = await initSmtp();
|
||||
setTransporter(transporter);
|
||||
|
||||
// initializing global feature set
|
||||
await EELicenseService.initGlobalFeatureSet();
|
||||
|
||||
// initializing auth strategies
|
||||
await initializeGoogleStrategy();
|
||||
await initializeGitHubStrategy()
|
||||
await initializeGitHubStrategy();
|
||||
await initializeGitLabStrategy();
|
||||
await initializeSamlStrategy();
|
||||
|
||||
@@ -73,6 +75,7 @@ export const setup = async () => {
|
||||
|
||||
// initializing the database connection
|
||||
await DatabaseService.initDatabase(await getMongoURL());
|
||||
await bootstrap({ transporter });
|
||||
|
||||
/**
|
||||
* NOTE: the order in this setup function is critical.
|
||||
@@ -92,7 +95,7 @@ export const setup = async () => {
|
||||
await backfillTrustedIps();
|
||||
await backfillUserAuthMethods();
|
||||
// await backfillPermission();
|
||||
await migrateRoleFromOwnerToAdmin()
|
||||
await migrateRoleFromOwnerToAdmin();
|
||||
|
||||
// re-encrypt any data previously encrypted under server hex 128-bit ENCRYPTION_KEY
|
||||
// to base64 256-bit ROOT_ENCRYPTION_KEY
|
||||
|
||||
24
backend/src/validation/admin.ts
Normal file
24
backend/src/validation/admin.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const UpdateServerConfigV1 = z.object({
|
||||
body: z.object({
|
||||
allowSignUp: z.boolean().optional()
|
||||
})
|
||||
});
|
||||
|
||||
export const SignupV1 = z.object({
|
||||
body: z.object({
|
||||
email: z.string().email().trim(),
|
||||
firstName: z.string().trim(),
|
||||
lastName: z.string().trim().optional(),
|
||||
protectedKey: z.string().trim(),
|
||||
protectedKeyIV: z.string().trim(),
|
||||
protectedKeyTag: z.string().trim(),
|
||||
publicKey: z.string().trim(),
|
||||
encryptedPrivateKey: z.string().trim(),
|
||||
encryptedPrivateKeyIV: z.string().trim(),
|
||||
encryptedPrivateKeyTag: z.string().trim(),
|
||||
salt: z.string().trim(),
|
||||
verifier: z.string().trim()
|
||||
})
|
||||
});
|
||||
Reference in New Issue
Block a user