mirror of
https://github.com/Infisical/infisical.git
synced 2025-08-24 20:43:19 +00:00
Compare commits
7 Commits
log-github
...
feat/opera
Author | SHA1 | Date | |
---|---|---|---|
|
6826b1c242 | ||
|
35012fde03 | ||
|
4b9e57ae61 | ||
|
eb27983990 | ||
|
fa311b032c | ||
|
71651f85fe | ||
|
d28d3449de |
189
backend/package-lock.json
generated
189
backend/package-lock.json
generated
@@ -38,7 +38,6 @@
|
|||||||
"@octokit/core": "^5.2.1",
|
"@octokit/core": "^5.2.1",
|
||||||
"@octokit/plugin-paginate-graphql": "^4.0.1",
|
"@octokit/plugin-paginate-graphql": "^4.0.1",
|
||||||
"@octokit/plugin-retry": "^5.0.5",
|
"@octokit/plugin-retry": "^5.0.5",
|
||||||
"@octokit/request": "8.4.1",
|
|
||||||
"@octokit/rest": "^20.0.2",
|
"@octokit/rest": "^20.0.2",
|
||||||
"@octokit/webhooks-types": "^7.3.1",
|
"@octokit/webhooks-types": "^7.3.1",
|
||||||
"@octopusdeploy/api-client": "^3.4.1",
|
"@octopusdeploy/api-client": "^3.4.1",
|
||||||
@@ -9778,6 +9777,18 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/auth-app/node_modules/@octokit/endpoint": {
|
||||||
|
"version": "10.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz",
|
||||||
|
"integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"universal-user-agent": "^7.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@octokit/auth-app/node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/auth-app/node_modules/@octokit/openapi-types": {
|
||||||
"version": "22.2.0",
|
"version": "22.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
||||||
@@ -9824,6 +9835,11 @@
|
|||||||
"node": "14 || >=16.14"
|
"node": "14 || >=16.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/auth-app/node_modules/universal-user-agent": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="
|
||||||
|
},
|
||||||
"node_modules/@octokit/auth-oauth-app": {
|
"node_modules/@octokit/auth-oauth-app": {
|
||||||
"version": "8.1.1",
|
"version": "8.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-8.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-8.1.1.tgz",
|
||||||
@@ -9839,6 +9855,18 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/auth-oauth-app/node_modules/@octokit/endpoint": {
|
||||||
|
"version": "10.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz",
|
||||||
|
"integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"universal-user-agent": "^7.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@octokit/auth-oauth-app/node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/auth-oauth-app/node_modules/@octokit/openapi-types": {
|
||||||
"version": "22.2.0",
|
"version": "22.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
||||||
@@ -9877,6 +9905,11 @@
|
|||||||
"@octokit/openapi-types": "^22.2.0"
|
"@octokit/openapi-types": "^22.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/auth-oauth-app/node_modules/universal-user-agent": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="
|
||||||
|
},
|
||||||
"node_modules/@octokit/auth-oauth-device": {
|
"node_modules/@octokit/auth-oauth-device": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-7.1.1.tgz",
|
||||||
@@ -9891,6 +9924,18 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/auth-oauth-device/node_modules/@octokit/endpoint": {
|
||||||
|
"version": "10.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz",
|
||||||
|
"integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"universal-user-agent": "^7.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@octokit/auth-oauth-device/node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/auth-oauth-device/node_modules/@octokit/openapi-types": {
|
||||||
"version": "22.2.0",
|
"version": "22.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
||||||
@@ -9929,6 +9974,11 @@
|
|||||||
"@octokit/openapi-types": "^22.2.0"
|
"@octokit/openapi-types": "^22.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/auth-oauth-device/node_modules/universal-user-agent": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="
|
||||||
|
},
|
||||||
"node_modules/@octokit/auth-oauth-user": {
|
"node_modules/@octokit/auth-oauth-user": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-5.1.1.tgz",
|
||||||
@@ -9944,6 +9994,18 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/auth-oauth-user/node_modules/@octokit/endpoint": {
|
||||||
|
"version": "10.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz",
|
||||||
|
"integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"universal-user-agent": "^7.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@octokit/auth-oauth-user/node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/auth-oauth-user/node_modules/@octokit/openapi-types": {
|
||||||
"version": "22.2.0",
|
"version": "22.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
||||||
@@ -9982,6 +10044,11 @@
|
|||||||
"@octokit/openapi-types": "^22.2.0"
|
"@octokit/openapi-types": "^22.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/auth-oauth-user/node_modules/universal-user-agent": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="
|
||||||
|
},
|
||||||
"node_modules/@octokit/auth-token": {
|
"node_modules/@octokit/auth-token": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
||||||
@@ -10035,38 +10102,32 @@
|
|||||||
"@octokit/openapi-types": "^24.2.0"
|
"@octokit/openapi-types": "^24.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/core/node_modules/universal-user-agent": {
|
|
||||||
"version": "6.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
|
|
||||||
"integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/endpoint": {
|
"node_modules/@octokit/endpoint": {
|
||||||
"version": "10.1.4",
|
"version": "9.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
|
||||||
"integrity": "sha512-OlYOlZIsfEVZm5HCSR8aSg02T2lbUWOsCQoPKfTXJwDzcHQBrVBGdGXb89dv2Kw2ToZaRtudp8O3ZIYoaOjKlA==",
|
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^14.0.0",
|
"@octokit/types": "^13.1.0",
|
||||||
"universal-user-agent": "^7.0.2"
|
"universal-user-agent": "^6.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": {
|
||||||
"version": "25.1.0",
|
"version": "24.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
||||||
"integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==",
|
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/endpoint/node_modules/@octokit/types": {
|
"node_modules/@octokit/endpoint/node_modules/@octokit/types": {
|
||||||
"version": "14.1.0",
|
"version": "13.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
||||||
"integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==",
|
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/openapi-types": "^25.1.0"
|
"@octokit/openapi-types": "^24.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/graphql": {
|
"node_modules/@octokit/graphql": {
|
||||||
@@ -10098,12 +10159,6 @@
|
|||||||
"@octokit/openapi-types": "^24.2.0"
|
"@octokit/openapi-types": "^24.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/graphql/node_modules/universal-user-agent": {
|
|
||||||
"version": "6.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
|
|
||||||
"integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/oauth-authorization-url": {
|
"node_modules/@octokit/oauth-authorization-url": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-7.1.1.tgz",
|
||||||
@@ -10126,6 +10181,18 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/oauth-methods/node_modules/@octokit/endpoint": {
|
||||||
|
"version": "10.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz",
|
||||||
|
"integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"universal-user-agent": "^7.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@octokit/oauth-methods/node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/oauth-methods/node_modules/@octokit/openapi-types": {
|
||||||
"version": "22.2.0",
|
"version": "22.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
||||||
@@ -10164,6 +10231,11 @@
|
|||||||
"@octokit/openapi-types": "^22.2.0"
|
"@octokit/openapi-types": "^22.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/oauth-methods/node_modules/universal-user-agent": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="
|
||||||
|
},
|
||||||
"node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/openapi-types": {
|
||||||
"version": "19.1.0",
|
"version": "19.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.1.0.tgz",
|
||||||
@@ -10304,54 +10376,31 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
|
||||||
"version": "24.2.0",
|
"version": "22.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
||||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
"integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg=="
|
||||||
"license": "MIT"
|
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request-error/node_modules/@octokit/types": {
|
"node_modules/@octokit/request-error/node_modules/@octokit/types": {
|
||||||
"version": "13.10.0",
|
"version": "13.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz",
|
||||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
"integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/openapi-types": "^24.2.0"
|
"@octokit/openapi-types": "^22.2.0"
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/request/node_modules/@octokit/endpoint": {
|
|
||||||
"version": "9.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
|
|
||||||
"integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@octokit/types": "^13.1.0",
|
|
||||||
"universal-user-agent": "^6.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request/node_modules/@octokit/openapi-types": {
|
"node_modules/@octokit/request/node_modules/@octokit/openapi-types": {
|
||||||
"version": "24.2.0",
|
"version": "22.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
||||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
"integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg=="
|
||||||
"license": "MIT"
|
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request/node_modules/@octokit/types": {
|
"node_modules/@octokit/request/node_modules/@octokit/types": {
|
||||||
"version": "13.10.0",
|
"version": "13.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz",
|
||||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
"integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/openapi-types": "^24.2.0"
|
"@octokit/openapi-types": "^22.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/request/node_modules/universal-user-agent": {
|
|
||||||
"version": "6.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
|
|
||||||
"integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/@octokit/rest": {
|
"node_modules/@octokit/rest": {
|
||||||
"version": "20.0.2",
|
"version": "20.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz",
|
||||||
@@ -18239,8 +18288,7 @@
|
|||||||
"node_modules/fast-content-type-parse": {
|
"node_modules/fast-content-type-parse": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz",
|
||||||
"integrity": "sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==",
|
"integrity": "sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ=="
|
||||||
"license": "MIT"
|
|
||||||
},
|
},
|
||||||
"node_modules/fast-copy": {
|
"node_modules/fast-copy": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
@@ -24728,12 +24776,6 @@
|
|||||||
"jsonwebtoken": "^9.0.2"
|
"jsonwebtoken": "^9.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/octokit-auth-probot/node_modules/universal-user-agent": {
|
|
||||||
"version": "6.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
|
|
||||||
"integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/odbc": {
|
"node_modules/odbc": {
|
||||||
"version": "2.4.9",
|
"version": "2.4.9",
|
||||||
"resolved": "https://registry.npmjs.org/odbc/-/odbc-2.4.9.tgz",
|
"resolved": "https://registry.npmjs.org/odbc/-/odbc-2.4.9.tgz",
|
||||||
@@ -30663,10 +30705,9 @@
|
|||||||
"integrity": "sha512-G5o6f95b5BggDGuUfKDApKaCgNYy2x7OdHY0zSMF081O0EJobw+1130VONhrA7ezGSV2FNOGyM+KQpQZAr9bIQ=="
|
"integrity": "sha512-G5o6f95b5BggDGuUfKDApKaCgNYy2x7OdHY0zSMF081O0EJobw+1130VONhrA7ezGSV2FNOGyM+KQpQZAr9bIQ=="
|
||||||
},
|
},
|
||||||
"node_modules/universal-user-agent": {
|
"node_modules/universal-user-agent": {
|
||||||
"version": "7.0.3",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
|
||||||
"integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==",
|
"integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ=="
|
||||||
"license": "ISC"
|
|
||||||
},
|
},
|
||||||
"node_modules/universalify": {
|
"node_modules/universalify": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
|
@@ -158,7 +158,6 @@
|
|||||||
"@octokit/core": "^5.2.1",
|
"@octokit/core": "^5.2.1",
|
||||||
"@octokit/plugin-paginate-graphql": "^4.0.1",
|
"@octokit/plugin-paginate-graphql": "^4.0.1",
|
||||||
"@octokit/plugin-retry": "^5.0.5",
|
"@octokit/plugin-retry": "^5.0.5",
|
||||||
"@octokit/request": "8.4.1",
|
|
||||||
"@octokit/rest": "^20.0.2",
|
"@octokit/rest": "^20.0.2",
|
||||||
"@octokit/webhooks-types": "^7.3.1",
|
"@octokit/webhooks-types": "^7.3.1",
|
||||||
"@octopusdeploy/api-client": "^3.4.1",
|
"@octopusdeploy/api-client": "^3.4.1",
|
||||||
|
@@ -1,19 +0,0 @@
|
|||||||
import { Knex } from "knex";
|
|
||||||
|
|
||||||
import { TableName } from "../schemas";
|
|
||||||
|
|
||||||
export async function up(knex: Knex): Promise<void> {
|
|
||||||
if (!(await knex.schema.hasColumn(TableName.Reminder, "fromDate"))) {
|
|
||||||
await knex.schema.alterTable(TableName.Reminder, (t) => {
|
|
||||||
t.timestamp("fromDate", { useTz: true }).nullable();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function down(knex: Knex): Promise<void> {
|
|
||||||
if (await knex.schema.hasColumn(TableName.Reminder, "fromDate")) {
|
|
||||||
await knex.schema.alterTable(TableName.Reminder, (t) => {
|
|
||||||
t.dropColumn("fromDate");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,8 +14,7 @@ export const RemindersSchema = z.object({
|
|||||||
repeatDays: z.number().nullable().optional(),
|
repeatDays: z.number().nullable().optional(),
|
||||||
nextReminderDate: z.date(),
|
nextReminderDate: z.date(),
|
||||||
createdAt: z.date(),
|
createdAt: z.date(),
|
||||||
updatedAt: z.date(),
|
updatedAt: z.date()
|
||||||
fromDate: z.date().nullable().optional()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TReminders = z.infer<typeof RemindersSchema>;
|
export type TReminders = z.infer<typeof RemindersSchema>;
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
// weird commonjs-related error in the CI requires us to do the import like this
|
// weird commonjs-related error in the CI requires us to do the import like this
|
||||||
import knex from "knex";
|
import knex from "knex";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
|
||||||
|
|
||||||
import { TDbClient } from "@app/db";
|
import { TDbClient } from "@app/db";
|
||||||
import { TableName, TAuditLogs } from "@app/db/schemas";
|
import { TableName, TAuditLogs } from "@app/db/schemas";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
|
||||||
import { DatabaseError, GatewayTimeoutError } from "@app/lib/errors";
|
import { DatabaseError, GatewayTimeoutError } from "@app/lib/errors";
|
||||||
import { ormify, selectAllTableCols, TOrmify } from "@app/lib/knex";
|
import { ormify, selectAllTableCols, TOrmify } from "@app/lib/knex";
|
||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
@@ -152,7 +150,6 @@ export const auditLogDALFactory = (db: TDbClient) => {
|
|||||||
|
|
||||||
// delete all audit log that have expired
|
// delete all audit log that have expired
|
||||||
const pruneAuditLog: TAuditLogDALFactory["pruneAuditLog"] = async (tx) => {
|
const pruneAuditLog: TAuditLogDALFactory["pruneAuditLog"] = async (tx) => {
|
||||||
const runPrune = async (dbClient: knex.Knex) => {
|
|
||||||
const AUDIT_LOG_PRUNE_BATCH_SIZE = 10000;
|
const AUDIT_LOG_PRUNE_BATCH_SIZE = 10000;
|
||||||
const MAX_RETRY_ON_FAILURE = 3;
|
const MAX_RETRY_ON_FAILURE = 3;
|
||||||
|
|
||||||
@@ -164,7 +161,7 @@ export const auditLogDALFactory = (db: TDbClient) => {
|
|||||||
logger.info(`${QueueName.DailyResourceCleanUp}: audit log started`);
|
logger.info(`${QueueName.DailyResourceCleanUp}: audit log started`);
|
||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
const findExpiredLogSubQuery = dbClient(TableName.AuditLog)
|
const findExpiredLogSubQuery = (tx || db)(TableName.AuditLog)
|
||||||
.where("expiresAt", "<", today)
|
.where("expiresAt", "<", today)
|
||||||
.where("createdAt", "<", today) // to use audit log partition
|
.where("createdAt", "<", today) // to use audit log partition
|
||||||
.orderBy(`${TableName.AuditLog}.createdAt`, "desc")
|
.orderBy(`${TableName.AuditLog}.createdAt`, "desc")
|
||||||
@@ -172,7 +169,7 @@ export const auditLogDALFactory = (db: TDbClient) => {
|
|||||||
.limit(AUDIT_LOG_PRUNE_BATCH_SIZE);
|
.limit(AUDIT_LOG_PRUNE_BATCH_SIZE);
|
||||||
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
deletedAuditLogIds = await dbClient(TableName.AuditLog)
|
deletedAuditLogIds = await (tx || db)(TableName.AuditLog)
|
||||||
.whereIn("id", findExpiredLogSubQuery)
|
.whereIn("id", findExpiredLogSubQuery)
|
||||||
.del()
|
.del()
|
||||||
.returning("id");
|
.returning("id");
|
||||||
@@ -191,31 +188,5 @@ export const auditLogDALFactory = (db: TDbClient) => {
|
|||||||
logger.info(`${QueueName.DailyResourceCleanUp}: audit log completed`);
|
logger.info(`${QueueName.DailyResourceCleanUp}: audit log completed`);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (tx) {
|
return { ...auditLogOrm, pruneAuditLog, find };
|
||||||
await runPrune(tx);
|
|
||||||
} else {
|
|
||||||
const QUERY_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
|
|
||||||
await db.transaction(async (trx) => {
|
|
||||||
await trx.raw(`SET statement_timeout = ${QUERY_TIMEOUT_MS}`);
|
|
||||||
await runPrune(trx);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const create: TAuditLogDALFactory["create"] = async (tx) => {
|
|
||||||
const config = getConfig();
|
|
||||||
|
|
||||||
if (config.DISABLE_AUDIT_LOG_STORAGE) {
|
|
||||||
return {
|
|
||||||
...tx,
|
|
||||||
id: uuidv4(),
|
|
||||||
createdAt: new Date(),
|
|
||||||
updatedAt: new Date()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return auditLogOrm.create(tx);
|
|
||||||
};
|
|
||||||
|
|
||||||
return { ...auditLogOrm, create, pruneAuditLog, find };
|
|
||||||
};
|
};
|
||||||
|
@@ -49,7 +49,6 @@ const baseSecretScanningDataSourceQuery = ({
|
|||||||
db.ref("encryptedCredentials").withSchema(TableName.AppConnection).as("connectionEncryptedCredentials"),
|
db.ref("encryptedCredentials").withSchema(TableName.AppConnection).as("connectionEncryptedCredentials"),
|
||||||
db.ref("description").withSchema(TableName.AppConnection).as("connectionDescription"),
|
db.ref("description").withSchema(TableName.AppConnection).as("connectionDescription"),
|
||||||
db.ref("version").withSchema(TableName.AppConnection).as("connectionVersion"),
|
db.ref("version").withSchema(TableName.AppConnection).as("connectionVersion"),
|
||||||
db.ref("gatewayId").withSchema(TableName.AppConnection).as("connectionGatewayId"),
|
|
||||||
db.ref("createdAt").withSchema(TableName.AppConnection).as("connectionCreatedAt"),
|
db.ref("createdAt").withSchema(TableName.AppConnection).as("connectionCreatedAt"),
|
||||||
db.ref("updatedAt").withSchema(TableName.AppConnection).as("connectionUpdatedAt"),
|
db.ref("updatedAt").withSchema(TableName.AppConnection).as("connectionUpdatedAt"),
|
||||||
db
|
db
|
||||||
@@ -83,7 +82,6 @@ const expandSecretScanningDataSource = <
|
|||||||
connectionUpdatedAt,
|
connectionUpdatedAt,
|
||||||
connectionVersion,
|
connectionVersion,
|
||||||
connectionIsPlatformManagedCredentials,
|
connectionIsPlatformManagedCredentials,
|
||||||
connectionGatewayId,
|
|
||||||
...el
|
...el
|
||||||
} = dataSource;
|
} = dataSource;
|
||||||
|
|
||||||
@@ -102,8 +100,7 @@ const expandSecretScanningDataSource = <
|
|||||||
createdAt: connectionCreatedAt,
|
createdAt: connectionCreatedAt,
|
||||||
updatedAt: connectionUpdatedAt,
|
updatedAt: connectionUpdatedAt,
|
||||||
version: connectionVersion,
|
version: connectionVersion,
|
||||||
isPlatformManagedCredentials: connectionIsPlatformManagedCredentials,
|
isPlatformManagedCredentials: connectionIsPlatformManagedCredentials
|
||||||
gatewayId: connectionGatewayId
|
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
};
|
};
|
||||||
|
@@ -59,7 +59,6 @@ const envSchema = z
|
|||||||
AUDIT_LOGS_DB_ROOT_CERT: zpStr(
|
AUDIT_LOGS_DB_ROOT_CERT: zpStr(
|
||||||
z.string().describe("Postgres database base64-encoded CA cert for Audit logs").optional()
|
z.string().describe("Postgres database base64-encoded CA cert for Audit logs").optional()
|
||||||
),
|
),
|
||||||
DISABLE_AUDIT_LOG_STORAGE: zodStrBool.default("false").optional().describe("Disable audit log storage"),
|
|
||||||
MAX_LEASE_LIMIT: z.coerce.number().default(10000),
|
MAX_LEASE_LIMIT: z.coerce.number().default(10000),
|
||||||
DB_ROOT_CERT: zpStr(z.string().describe("Postgres database base64-encoded CA cert").optional()),
|
DB_ROOT_CERT: zpStr(z.string().describe("Postgres database base64-encoded CA cert").optional()),
|
||||||
DB_HOST: zpStr(z.string().describe("Postgres database host").optional()),
|
DB_HOST: zpStr(z.string().describe("Postgres database host").optional()),
|
||||||
@@ -483,15 +482,6 @@ export const overwriteSchema: {
|
|||||||
fields: { key: keyof TEnvConfig; description?: string }[];
|
fields: { key: keyof TEnvConfig; description?: string }[];
|
||||||
};
|
};
|
||||||
} = {
|
} = {
|
||||||
auditLogs: {
|
|
||||||
name: "Audit Logs",
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
key: "DISABLE_AUDIT_LOG_STORAGE",
|
|
||||||
description: "Disable audit log storage"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
aws: {
|
aws: {
|
||||||
name: "AWS",
|
name: "AWS",
|
||||||
fields: [
|
fields: [
|
||||||
|
@@ -2144,8 +2144,7 @@ export const registerRoutes = async (
|
|||||||
inviteOnlySignup: z.boolean().optional(),
|
inviteOnlySignup: z.boolean().optional(),
|
||||||
redisConfigured: z.boolean().optional(),
|
redisConfigured: z.boolean().optional(),
|
||||||
secretScanningConfigured: z.boolean().optional(),
|
secretScanningConfigured: z.boolean().optional(),
|
||||||
samlDefaultOrgSlug: z.string().optional(),
|
samlDefaultOrgSlug: z.string().optional()
|
||||||
auditLogStorageDisabled: z.boolean().optional()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2172,8 +2171,7 @@ export const registerRoutes = async (
|
|||||||
inviteOnlySignup: Boolean(serverCfg.allowSignUp),
|
inviteOnlySignup: Boolean(serverCfg.allowSignUp),
|
||||||
redisConfigured: cfg.isRedisConfigured,
|
redisConfigured: cfg.isRedisConfigured,
|
||||||
secretScanningConfigured: cfg.isSecretScanningConfigured,
|
secretScanningConfigured: cfg.isSecretScanningConfigured,
|
||||||
samlDefaultOrgSlug: cfg.samlDefaultOrgSlug,
|
samlDefaultOrgSlug: cfg.samlDefaultOrgSlug
|
||||||
auditLogStorageDisabled: Boolean(cfg.DISABLE_AUDIT_LOG_STORAGE)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -22,7 +22,6 @@ export const registerSecretReminderRouter = async (server: FastifyZodProvider) =
|
|||||||
message: z.string().trim().max(1024).optional(),
|
message: z.string().trim().max(1024).optional(),
|
||||||
repeatDays: z.number().min(1).nullable().optional(),
|
repeatDays: z.number().min(1).nullable().optional(),
|
||||||
nextReminderDate: z.string().datetime().nullable().optional(),
|
nextReminderDate: z.string().datetime().nullable().optional(),
|
||||||
fromDate: z.string().datetime().nullable().optional(),
|
|
||||||
recipients: z.string().array().optional()
|
recipients: z.string().array().optional()
|
||||||
})
|
})
|
||||||
.refine((data) => {
|
.refine((data) => {
|
||||||
@@ -46,7 +45,6 @@ export const registerSecretReminderRouter = async (server: FastifyZodProvider) =
|
|||||||
message: req.body.message,
|
message: req.body.message,
|
||||||
repeatDays: req.body.repeatDays,
|
repeatDays: req.body.repeatDays,
|
||||||
nextReminderDate: req.body.nextReminderDate,
|
nextReminderDate: req.body.nextReminderDate,
|
||||||
fromDate: req.body.fromDate,
|
|
||||||
recipients: req.body.recipients
|
recipients: req.body.recipients
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
import { createAppAuth } from "@octokit/auth-app";
|
import { createAppAuth } from "@octokit/auth-app";
|
||||||
import { request } from "@octokit/request";
|
|
||||||
import { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios";
|
import { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios";
|
||||||
import https from "https";
|
import https from "https";
|
||||||
import RE2 from "re2";
|
import RE2 from "re2";
|
||||||
@@ -13,6 +12,7 @@ import { GatewayProxyProtocol, withGatewayProxy } from "@app/lib/gateway";
|
|||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
|
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
|
||||||
import { getAppConnectionMethodName } from "@app/services/app-connection/app-connection-fns";
|
import { getAppConnectionMethodName } from "@app/services/app-connection/app-connection-fns";
|
||||||
|
import { IntegrationUrls } from "@app/services/integration-auth/integration-list";
|
||||||
|
|
||||||
import { AppConnection } from "../app-connection-enums";
|
import { AppConnection } from "../app-connection-enums";
|
||||||
import { GitHubConnectionMethod } from "./github-connection-enums";
|
import { GitHubConnectionMethod } from "./github-connection-enums";
|
||||||
@@ -30,23 +30,6 @@ export const getGitHubConnectionListItem = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getGitHubInstanceApiUrl = async (config: {
|
|
||||||
credentials: Pick<TGitHubConnectionConfig["credentials"], "host" | "instanceType">;
|
|
||||||
}) => {
|
|
||||||
const host = config.credentials.host || "github.com";
|
|
||||||
|
|
||||||
await blockLocalAndPrivateIpAddresses(host);
|
|
||||||
|
|
||||||
let apiBase: string;
|
|
||||||
if (config.credentials.instanceType === "server") {
|
|
||||||
apiBase = `${host}/api/v3`;
|
|
||||||
} else {
|
|
||||||
apiBase = `api.${host}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return apiBase;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const requestWithGitHubGateway = async <T>(
|
export const requestWithGitHubGateway = async <T>(
|
||||||
appConnection: { gatewayId?: string | null },
|
appConnection: { gatewayId?: string | null },
|
||||||
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">,
|
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">,
|
||||||
@@ -90,10 +73,7 @@ export const requestWithGitHubGateway = async <T>(
|
|||||||
return await httpRequest.request(finalRequestConfig);
|
return await httpRequest.request(finalRequestConfig);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const axiosError = error as AxiosError;
|
const axiosError = error as AxiosError;
|
||||||
logger.error(
|
logger.error("Error during GitHub gateway request:", axiosError.message, axiosError.response?.data);
|
||||||
{ message: axiosError.message, data: axiosError.response?.data },
|
|
||||||
"Error during GitHub gateway request:"
|
|
||||||
);
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -132,10 +112,7 @@ export const getGitHubAppAuthToken = async (appConnection: TGitHubConnection) =>
|
|||||||
const appAuth = createAppAuth({
|
const appAuth = createAppAuth({
|
||||||
appId,
|
appId,
|
||||||
privateKey: appPrivateKey,
|
privateKey: appPrivateKey,
|
||||||
installationId: appConnection.credentials.installationId,
|
installationId: appConnection.credentials.installationId
|
||||||
request: request.defaults({
|
|
||||||
baseUrl: `https://${await getGitHubInstanceApiUrl(appConnection)}`
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { token } = await appAuth({ type: "installation" });
|
const { token } = await appAuth({ type: "installation" });
|
||||||
@@ -164,7 +141,7 @@ export const makePaginatedGitHubRequest = async <T, R = T[]>(
|
|||||||
|
|
||||||
const token =
|
const token =
|
||||||
method === GitHubConnectionMethod.OAuth ? credentials.accessToken : await getGitHubAppAuthToken(appConnection);
|
method === GitHubConnectionMethod.OAuth ? credentials.accessToken : await getGitHubAppAuthToken(appConnection);
|
||||||
let url: string | null = `https://${await getGitHubInstanceApiUrl(appConnection)}${path}`;
|
let url: string | null = `https://api.${credentials.host || "github.com"}${path}`;
|
||||||
let results: T[] = [];
|
let results: T[] = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
|
||||||
@@ -348,8 +325,6 @@ export const validateGitHubConnectionCredentials = async (
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
logger.error(e, "Unable to verify GitHub connection");
|
|
||||||
|
|
||||||
if (e instanceof BadRequestError) {
|
if (e instanceof BadRequestError) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
@@ -380,7 +355,7 @@ export const validateGitHubConnectionCredentials = async (
|
|||||||
};
|
};
|
||||||
}[];
|
}[];
|
||||||
}>(config, gatewayService, {
|
}>(config, gatewayService, {
|
||||||
url: `https://${await getGitHubInstanceApiUrl(config)}/user/installations`,
|
url: IntegrationUrls.GITHUB_USER_INSTALLATIONS.replace("api.github.com", `api.${host}`),
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
Authorization: `Bearer ${tokenResp.data.access_token}`,
|
Authorization: `Bearer ${tokenResp.data.access_token}`,
|
||||||
@@ -402,15 +377,11 @@ export const validateGitHubConnectionCredentials = async (
|
|||||||
switch (method) {
|
switch (method) {
|
||||||
case GitHubConnectionMethod.App:
|
case GitHubConnectionMethod.App:
|
||||||
return {
|
return {
|
||||||
installationId: credentials.installationId,
|
installationId: credentials.installationId
|
||||||
instanceType: credentials.instanceType,
|
|
||||||
host: credentials.host
|
|
||||||
};
|
};
|
||||||
case GitHubConnectionMethod.OAuth:
|
case GitHubConnectionMethod.OAuth:
|
||||||
return {
|
return {
|
||||||
accessToken: tokenResp.data.access_token,
|
accessToken: tokenResp.data.access_token
|
||||||
instanceType: credentials.instanceType,
|
|
||||||
host: credentials.host
|
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
throw new InternalServerError({
|
throw new InternalServerError({
|
||||||
|
@@ -10,59 +10,26 @@ import {
|
|||||||
|
|
||||||
import { GitHubConnectionMethod } from "./github-connection-enums";
|
import { GitHubConnectionMethod } from "./github-connection-enums";
|
||||||
|
|
||||||
export const GitHubConnectionOAuthInputCredentialsSchema = z.union([
|
export const GitHubConnectionOAuthInputCredentialsSchema = z.object({
|
||||||
z.object({
|
|
||||||
code: z.string().trim().min(1, "OAuth code required"),
|
code: z.string().trim().min(1, "OAuth code required"),
|
||||||
instanceType: z.literal("server"),
|
|
||||||
host: z.string().trim().min(1, "Host is required for server instance type")
|
|
||||||
}),
|
|
||||||
z.object({
|
|
||||||
code: z.string().trim().min(1, "OAuth code required"),
|
|
||||||
instanceType: z.literal("cloud").optional(),
|
|
||||||
host: z.string().trim().optional()
|
host: z.string().trim().optional()
|
||||||
})
|
});
|
||||||
]);
|
|
||||||
|
|
||||||
export const GitHubConnectionAppInputCredentialsSchema = z.union([
|
export const GitHubConnectionAppInputCredentialsSchema = z.object({
|
||||||
z.object({
|
|
||||||
code: z.string().trim().min(1, "GitHub App code required"),
|
code: z.string().trim().min(1, "GitHub App code required"),
|
||||||
installationId: z.string().min(1, "GitHub App Installation ID required"),
|
installationId: z.string().min(1, "GitHub App Installation ID required"),
|
||||||
instanceType: z.literal("server"),
|
|
||||||
host: z.string().trim().min(1, "Host is required for server instance type")
|
|
||||||
}),
|
|
||||||
z.object({
|
|
||||||
code: z.string().trim().min(1, "GitHub App code required"),
|
|
||||||
installationId: z.string().min(1, "GitHub App Installation ID required"),
|
|
||||||
instanceType: z.literal("cloud").optional(),
|
|
||||||
host: z.string().trim().optional()
|
host: z.string().trim().optional()
|
||||||
})
|
});
|
||||||
]);
|
|
||||||
|
|
||||||
export const GitHubConnectionOAuthOutputCredentialsSchema = z.union([
|
export const GitHubConnectionOAuthOutputCredentialsSchema = z.object({
|
||||||
z.object({
|
|
||||||
accessToken: z.string(),
|
accessToken: z.string(),
|
||||||
instanceType: z.literal("server"),
|
|
||||||
host: z.string().trim().min(1)
|
|
||||||
}),
|
|
||||||
z.object({
|
|
||||||
accessToken: z.string(),
|
|
||||||
instanceType: z.literal("cloud").optional(),
|
|
||||||
host: z.string().trim().optional()
|
host: z.string().trim().optional()
|
||||||
})
|
});
|
||||||
]);
|
|
||||||
|
|
||||||
export const GitHubConnectionAppOutputCredentialsSchema = z.union([
|
export const GitHubConnectionAppOutputCredentialsSchema = z.object({
|
||||||
z.object({
|
|
||||||
installationId: z.string(),
|
installationId: z.string(),
|
||||||
instanceType: z.literal("server"),
|
|
||||||
host: z.string().trim().min(1)
|
|
||||||
}),
|
|
||||||
z.object({
|
|
||||||
installationId: z.string(),
|
|
||||||
instanceType: z.literal("cloud").optional(),
|
|
||||||
host: z.string().trim().optional()
|
host: z.string().trim().optional()
|
||||||
})
|
});
|
||||||
]);
|
|
||||||
|
|
||||||
export const ValidateGitHubConnectionCredentialsSchema = z.discriminatedUnion("method", [
|
export const ValidateGitHubConnectionCredentialsSchema = z.discriminatedUnion("method", [
|
||||||
z.object({
|
z.object({
|
||||||
@@ -117,17 +84,11 @@ export const GitHubConnectionSchema = z.intersection(
|
|||||||
export const SanitizedGitHubConnectionSchema = z.discriminatedUnion("method", [
|
export const SanitizedGitHubConnectionSchema = z.discriminatedUnion("method", [
|
||||||
BaseGitHubConnectionSchema.extend({
|
BaseGitHubConnectionSchema.extend({
|
||||||
method: z.literal(GitHubConnectionMethod.App),
|
method: z.literal(GitHubConnectionMethod.App),
|
||||||
credentials: z.object({
|
credentials: GitHubConnectionAppOutputCredentialsSchema.pick({})
|
||||||
instanceType: z.union([z.literal("server"), z.literal("cloud")]).optional(),
|
|
||||||
host: z.string().optional()
|
|
||||||
})
|
|
||||||
}),
|
}),
|
||||||
BaseGitHubConnectionSchema.extend({
|
BaseGitHubConnectionSchema.extend({
|
||||||
method: z.literal(GitHubConnectionMethod.OAuth),
|
method: z.literal(GitHubConnectionMethod.OAuth),
|
||||||
credentials: z.object({
|
credentials: GitHubConnectionOAuthOutputCredentialsSchema.pick({})
|
||||||
instanceType: z.union([z.literal("server"), z.literal("cloud")]).optional(),
|
|
||||||
host: z.string().optional()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@@ -15,15 +15,10 @@ export const validateAltNameField = z
|
|||||||
.trim()
|
.trim()
|
||||||
.refine(
|
.refine(
|
||||||
(name) => {
|
(name) => {
|
||||||
return (
|
return isFQDN(name, { allow_wildcard: true }) || z.string().email().safeParse(name).success || isValidIp(name);
|
||||||
isFQDN(name, { allow_wildcard: true, require_tld: false }) ||
|
|
||||||
z.string().url().safeParse(name).success ||
|
|
||||||
z.string().email().safeParse(name).success ||
|
|
||||||
isValidIp(name)
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
message: "SAN must be a valid hostname, email address, IP address or URL"
|
message: "SAN must be a valid hostname, email address, or IP address"
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -44,15 +39,10 @@ export const validateAltNamesField = z
|
|||||||
if (data === "") return true;
|
if (data === "") return true;
|
||||||
// Split and validate each alt name
|
// Split and validate each alt name
|
||||||
return data.split(", ").every((name) => {
|
return data.split(", ").every((name) => {
|
||||||
return (
|
return isFQDN(name, { allow_wildcard: true }) || z.string().email().safeParse(name).success || isValidIp(name);
|
||||||
isFQDN(name, { allow_wildcard: true, require_tld: false }) ||
|
|
||||||
z.string().url().safeParse(name).success ||
|
|
||||||
z.string().email().safeParse(name).success ||
|
|
||||||
isValidIp(name)
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
message: "Each alt name must be a valid hostname, email address, IP address or URL"
|
message: "Each alt name must be a valid hostname or email address"
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@@ -152,7 +152,7 @@ export const InternalCertificateAuthorityFns = ({
|
|||||||
extensions.push(extendedKeyUsagesExtension);
|
extensions.push(extendedKeyUsagesExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
let altNamesArray: { type: "email" | "dns" | "ip" | "url"; value: string }[] = [];
|
let altNamesArray: { type: "email" | "dns"; value: string }[] = [];
|
||||||
|
|
||||||
if (subscriber.subjectAlternativeNames?.length) {
|
if (subscriber.subjectAlternativeNames?.length) {
|
||||||
altNamesArray = subscriber.subjectAlternativeNames.map((altName) => {
|
altNamesArray = subscriber.subjectAlternativeNames.map((altName) => {
|
||||||
@@ -160,18 +160,10 @@ export const InternalCertificateAuthorityFns = ({
|
|||||||
return { type: "email", value: altName };
|
return { type: "email", value: altName };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFQDN(altName, { allow_wildcard: true, require_tld: false })) {
|
if (isFQDN(altName, { allow_wildcard: true })) {
|
||||||
return { type: "dns", value: altName };
|
return { type: "dns", value: altName };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (z.string().url().safeParse(altName).success) {
|
|
||||||
return { type: "url", value: altName };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (z.string().ip().safeParse(altName).success) {
|
|
||||||
return { type: "ip", value: altName };
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new BadRequestError({ message: `Invalid SAN entry: ${altName}` });
|
throw new BadRequestError({ message: `Invalid SAN entry: ${altName}` });
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -426,7 +418,7 @@ export const InternalCertificateAuthorityFns = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let altNamesArray: { type: "email" | "dns" | "ip" | "url"; value: string }[] = [];
|
let altNamesArray: { type: "email" | "dns"; value: string }[] = [];
|
||||||
|
|
||||||
if (altNames) {
|
if (altNames) {
|
||||||
altNamesArray = altNames.split(",").map((altName) => {
|
altNamesArray = altNames.split(",").map((altName) => {
|
||||||
@@ -434,18 +426,10 @@ export const InternalCertificateAuthorityFns = ({
|
|||||||
return { type: "email", value: altName };
|
return { type: "email", value: altName };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFQDN(altName, { allow_wildcard: true, require_tld: false })) {
|
if (isFQDN(altName, { allow_wildcard: true })) {
|
||||||
return { type: "dns", value: altName };
|
return { type: "dns", value: altName };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (z.string().url().safeParse(altName).success) {
|
|
||||||
return { type: "url", value: altName };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (z.string().ip().safeParse(altName).success) {
|
|
||||||
return { type: "ip", value: altName };
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new BadRequestError({ message: `Invalid SAN entry: ${altName}` });
|
throw new BadRequestError({ message: `Invalid SAN entry: ${altName}` });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -79,34 +79,26 @@ export const reminderServiceFactory = ({
|
|||||||
repeatDays,
|
repeatDays,
|
||||||
nextReminderDate: nextReminderDateInput,
|
nextReminderDate: nextReminderDateInput,
|
||||||
recipients,
|
recipients,
|
||||||
projectId,
|
projectId
|
||||||
fromDate: fromDateInput
|
|
||||||
}: {
|
}: {
|
||||||
secretId?: string;
|
secretId?: string;
|
||||||
message?: string | null;
|
message?: string | null;
|
||||||
repeatDays?: number | null;
|
repeatDays?: number | null;
|
||||||
nextReminderDate?: string | null;
|
nextReminderDate?: string | null;
|
||||||
recipients?: string[] | null;
|
recipients?: string[] | null;
|
||||||
fromDate?: string | null;
|
|
||||||
projectId: string;
|
projectId: string;
|
||||||
}) => {
|
}) => {
|
||||||
if (!secretId) {
|
if (!secretId) {
|
||||||
throw new BadRequestError({ message: "secretId is required" });
|
throw new BadRequestError({ message: "secretId is required" });
|
||||||
}
|
}
|
||||||
let nextReminderDate;
|
let nextReminderDate;
|
||||||
let fromDate;
|
|
||||||
if (nextReminderDateInput) {
|
if (nextReminderDateInput) {
|
||||||
nextReminderDate = new Date(nextReminderDateInput);
|
nextReminderDate = new Date(nextReminderDateInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (repeatDays) {
|
if (repeatDays && repeatDays > 0) {
|
||||||
if (fromDateInput) {
|
|
||||||
fromDate = new Date(fromDateInput);
|
|
||||||
nextReminderDate = fromDate;
|
|
||||||
} else {
|
|
||||||
nextReminderDate = $addDays(repeatDays);
|
nextReminderDate = $addDays(repeatDays);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!nextReminderDate) {
|
if (!nextReminderDate) {
|
||||||
throw new BadRequestError({ message: "repeatDays must be a positive number" });
|
throw new BadRequestError({ message: "repeatDays must be a positive number" });
|
||||||
@@ -120,8 +112,7 @@ export const reminderServiceFactory = ({
|
|||||||
await reminderDAL.updateById(existingReminder.id, {
|
await reminderDAL.updateById(existingReminder.id, {
|
||||||
message,
|
message,
|
||||||
repeatDays,
|
repeatDays,
|
||||||
nextReminderDate,
|
nextReminderDate
|
||||||
fromDate
|
|
||||||
});
|
});
|
||||||
reminderId = existingReminder.id;
|
reminderId = existingReminder.id;
|
||||||
} else {
|
} else {
|
||||||
@@ -130,8 +121,7 @@ export const reminderServiceFactory = ({
|
|||||||
secretId,
|
secretId,
|
||||||
message,
|
message,
|
||||||
repeatDays,
|
repeatDays,
|
||||||
nextReminderDate,
|
nextReminderDate
|
||||||
fromDate
|
|
||||||
});
|
});
|
||||||
reminderId = newReminder.id;
|
reminderId = newReminder.id;
|
||||||
}
|
}
|
||||||
@@ -290,29 +280,15 @@ export const reminderServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const processedReminders = remindersData.map(
|
const processedReminders = remindersData.map(
|
||||||
({
|
({ secretId, message, repeatDays, nextReminderDate: nextReminderDateInput, recipients, projectId }) => {
|
||||||
secretId,
|
|
||||||
message,
|
|
||||||
repeatDays,
|
|
||||||
nextReminderDate: nextReminderDateInput,
|
|
||||||
recipients,
|
|
||||||
projectId,
|
|
||||||
fromDate: fromDateInput
|
|
||||||
}) => {
|
|
||||||
let nextReminderDate;
|
let nextReminderDate;
|
||||||
let fromDate;
|
|
||||||
if (nextReminderDateInput) {
|
if (nextReminderDateInput) {
|
||||||
nextReminderDate = new Date(nextReminderDateInput);
|
nextReminderDate = new Date(nextReminderDateInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (repeatDays && !nextReminderDate) {
|
if (repeatDays && repeatDays > 0 && !nextReminderDate) {
|
||||||
if (fromDateInput) {
|
|
||||||
fromDate = new Date(fromDateInput);
|
|
||||||
nextReminderDate = fromDate;
|
|
||||||
} else {
|
|
||||||
nextReminderDate = $addDays(repeatDays);
|
nextReminderDate = $addDays(repeatDays);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!nextReminderDate) {
|
if (!nextReminderDate) {
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
@@ -326,19 +302,17 @@ export const reminderServiceFactory = ({
|
|||||||
repeatDays,
|
repeatDays,
|
||||||
nextReminderDate,
|
nextReminderDate,
|
||||||
recipients: recipients ? [...new Set(recipients)] : [],
|
recipients: recipients ? [...new Set(recipients)] : [],
|
||||||
projectId,
|
projectId
|
||||||
fromDate
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const newReminders = await reminderDAL.insertMany(
|
const newReminders = await reminderDAL.insertMany(
|
||||||
processedReminders.map(({ secretId, message, repeatDays, nextReminderDate, fromDate }) => ({
|
processedReminders.map(({ secretId, message, repeatDays, nextReminderDate }) => ({
|
||||||
secretId,
|
secretId,
|
||||||
message,
|
message,
|
||||||
repeatDays,
|
repeatDays,
|
||||||
nextReminderDate,
|
nextReminderDate
|
||||||
fromDate
|
|
||||||
})),
|
})),
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
|
@@ -8,7 +8,6 @@ export type TReminder = {
|
|||||||
message?: string | null;
|
message?: string | null;
|
||||||
repeatDays?: number | null;
|
repeatDays?: number | null;
|
||||||
nextReminderDate: Date;
|
nextReminderDate: Date;
|
||||||
fromDate?: Date | null;
|
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
};
|
};
|
||||||
@@ -22,7 +21,6 @@ export type TCreateReminderDTO = {
|
|||||||
secretId?: string;
|
secretId?: string;
|
||||||
message?: string | null;
|
message?: string | null;
|
||||||
repeatDays?: number | null;
|
repeatDays?: number | null;
|
||||||
fromDate?: string | null;
|
|
||||||
nextReminderDate?: string | null;
|
nextReminderDate?: string | null;
|
||||||
recipients?: string[] | null;
|
recipients?: string[] | null;
|
||||||
};
|
};
|
||||||
@@ -33,7 +31,6 @@ export type TBatchCreateReminderDTO = {
|
|||||||
message?: string | null;
|
message?: string | null;
|
||||||
repeatDays?: number | null;
|
repeatDays?: number | null;
|
||||||
nextReminderDate?: string | Date | null;
|
nextReminderDate?: string | Date | null;
|
||||||
fromDate?: Date | null;
|
|
||||||
recipients?: string[] | null;
|
recipients?: string[] | null;
|
||||||
projectId?: string;
|
projectId?: string;
|
||||||
}[];
|
}[];
|
||||||
@@ -98,7 +95,6 @@ export interface TReminderServiceFactory {
|
|||||||
nextReminderDate?: string | null;
|
nextReminderDate?: string | null;
|
||||||
recipients?: string[] | null;
|
recipients?: string[] | null;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
fromDate?: string | null;
|
|
||||||
}) => Promise<{
|
}) => Promise<{
|
||||||
id: string;
|
id: string;
|
||||||
created: boolean;
|
created: boolean;
|
||||||
|
@@ -3,7 +3,6 @@ import sodium from "libsodium-wrappers";
|
|||||||
import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service";
|
import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service";
|
||||||
import {
|
import {
|
||||||
getGitHubAppAuthToken,
|
getGitHubAppAuthToken,
|
||||||
getGitHubInstanceApiUrl,
|
|
||||||
GitHubConnectionMethod,
|
GitHubConnectionMethod,
|
||||||
makePaginatedGitHubRequest,
|
makePaginatedGitHubRequest,
|
||||||
requestWithGitHubGateway
|
requestWithGitHubGateway
|
||||||
@@ -74,7 +73,7 @@ const getPublicKey = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const response = await requestWithGitHubGateway<TGitHubPublicKey>(connection, gatewayService, {
|
const response = await requestWithGitHubGateway<TGitHubPublicKey>(connection, gatewayService, {
|
||||||
url: `https://${await getGitHubInstanceApiUrl(connection)}${path}`,
|
url: `https://api.${connection.credentials.host || "github.com"}${path}`,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "application/vnd.github+json",
|
Accept: "application/vnd.github+json",
|
||||||
@@ -112,7 +111,7 @@ const deleteSecret = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
await requestWithGitHubGateway(connection, gatewayService, {
|
await requestWithGitHubGateway(connection, gatewayService, {
|
||||||
url: `https://${await getGitHubInstanceApiUrl(connection)}${path}`,
|
url: `https://api.${connection.credentials.host || "github.com"}${path}`,
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "application/vnd.github+json",
|
Accept: "application/vnd.github+json",
|
||||||
@@ -158,7 +157,7 @@ const putSecret = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
await requestWithGitHubGateway(connection, gatewayService, {
|
await requestWithGitHubGateway(connection, gatewayService, {
|
||||||
url: `https://${await getGitHubInstanceApiUrl(connection)}${path}`,
|
url: `https://api.${connection.credentials.host || "github.com"}${path}`,
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "application/vnd.github+json",
|
Accept: "application/vnd.github+json",
|
||||||
|
@@ -30,7 +30,6 @@ const baseSecretSyncQuery = ({ filter, db, tx }: { db: TDbClient; filter?: Secre
|
|||||||
db.ref("encryptedCredentials").withSchema(TableName.AppConnection).as("connectionEncryptedCredentials"),
|
db.ref("encryptedCredentials").withSchema(TableName.AppConnection).as("connectionEncryptedCredentials"),
|
||||||
db.ref("description").withSchema(TableName.AppConnection).as("connectionDescription"),
|
db.ref("description").withSchema(TableName.AppConnection).as("connectionDescription"),
|
||||||
db.ref("version").withSchema(TableName.AppConnection).as("connectionVersion"),
|
db.ref("version").withSchema(TableName.AppConnection).as("connectionVersion"),
|
||||||
db.ref("gatewayId").withSchema(TableName.AppConnection).as("connectionGatewayId"),
|
|
||||||
db.ref("createdAt").withSchema(TableName.AppConnection).as("connectionCreatedAt"),
|
db.ref("createdAt").withSchema(TableName.AppConnection).as("connectionCreatedAt"),
|
||||||
db.ref("updatedAt").withSchema(TableName.AppConnection).as("connectionUpdatedAt"),
|
db.ref("updatedAt").withSchema(TableName.AppConnection).as("connectionUpdatedAt"),
|
||||||
db
|
db
|
||||||
@@ -66,7 +65,6 @@ const expandSecretSync = (
|
|||||||
connectionUpdatedAt,
|
connectionUpdatedAt,
|
||||||
connectionVersion,
|
connectionVersion,
|
||||||
connectionIsPlatformManagedCredentials,
|
connectionIsPlatformManagedCredentials,
|
||||||
connectionGatewayId,
|
|
||||||
...el
|
...el
|
||||||
} = secretSync;
|
} = secretSync;
|
||||||
|
|
||||||
@@ -85,8 +83,7 @@ const expandSecretSync = (
|
|||||||
createdAt: connectionCreatedAt,
|
createdAt: connectionCreatedAt,
|
||||||
updatedAt: connectionUpdatedAt,
|
updatedAt: connectionUpdatedAt,
|
||||||
version: connectionVersion,
|
version: connectionVersion,
|
||||||
isPlatformManagedCredentials: connectionIsPlatformManagedCredentials,
|
isPlatformManagedCredentials: connectionIsPlatformManagedCredentials
|
||||||
gatewayId: connectionGatewayId
|
|
||||||
},
|
},
|
||||||
folder: folder
|
folder: folder
|
||||||
? {
|
? {
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface AccessApprovalRequestTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface AccessApprovalRequestTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
projectName: string;
|
projectName: string;
|
||||||
@@ -40,15 +38,18 @@ export const AccessApprovalRequestTemplate = ({
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
You have a new access approval request pending review for the project <strong>{projectName}</strong>
|
You have a new access approval request pending review for the project <strong>{projectName}</strong>
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-black text-[14px] leading-[24px]">
|
<Text className="text-black text-[14px] leading-[24px]">
|
||||||
<strong>{requesterFullName}</strong> (<BaseLink href={`mailto:${requesterEmail}`}>{requesterEmail}</BaseLink>)
|
<strong>{requesterFullName}</strong> (
|
||||||
has requested {isTemporary ? "temporary" : "permanent"} access to <strong>{secretPath}</strong> in the{" "}
|
<Link href={`mailto:${requesterEmail}`} className="text-slate-700 no-underline">
|
||||||
|
{requesterEmail}
|
||||||
|
</Link>
|
||||||
|
) has requested {isTemporary ? "temporary" : "permanent"} access to <strong>{secretPath}</strong> in the{" "}
|
||||||
<strong>{environment}</strong> environment.
|
<strong>{environment}</strong> environment.
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
{isTemporary && (
|
{isTemporary && (
|
||||||
<Text className="text-[14px] text-red-600 leading-[24px]">
|
<Text className="text-[14px] text-red-500 leading-[24px]">
|
||||||
<strong>This access will expire {expiresIn} after approval.</strong>
|
<strong>This access will expire {expiresIn} after approval.</strong>
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
@@ -66,8 +67,13 @@ export const AccessApprovalRequestTemplate = ({
|
|||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={approvalUrl}>Review Request</BaseButton>
|
<Button
|
||||||
|
href={approvalUrl}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
Review Request
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,18 +0,0 @@
|
|||||||
import { Button } from "@react-email/components";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
href: string;
|
|
||||||
children: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const BaseButton = ({ href, children }: Props) => {
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
href={href}
|
|
||||||
className="rounded-[8px] py-[12px] px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
};
|
|
@@ -16,21 +16,23 @@ export const BaseEmailWrapper = ({ title, preview, children, siteUrl }: BaseEmai
|
|||||||
<Body className="bg-gray-300 my-auto mx-auto font-sans px-[8px] py-[4px]">
|
<Body className="bg-gray-300 my-auto mx-auto font-sans px-[8px] py-[4px]">
|
||||||
<Preview>{preview}</Preview>
|
<Preview>{preview}</Preview>
|
||||||
<Container className="bg-white rounded-xl my-[40px] mx-auto pb-[0px] max-w-[500px]">
|
<Container className="bg-white rounded-xl my-[40px] mx-auto pb-[0px] max-w-[500px]">
|
||||||
<Section className="mb-[24px] px-[24px] mt-[24px]">
|
<Section className="border-0 border-b border-[#d1e309] border-solid bg-[#EBF852] mb-[44px] h-[10px] rounded-t-xl" />
|
||||||
|
<Section className="px-[32px] mb-[18px]">
|
||||||
|
<Section className="w-[48px] h-[48px] border border-solid border-gray-300 rounded-full bg-gray-100 mx-auto">
|
||||||
<Img
|
<Img
|
||||||
src="https://infisical.com/_next/image?url=%2Fimages%2Flogo-black.png&w=64&q=75"
|
src={`https://infisical.com/_next/image?url=%2Fimages%2Flogo-black.png&w=64&q=75`}
|
||||||
width="36"
|
width="32"
|
||||||
alt="Infisical Logo"
|
alt="Infisical Logo"
|
||||||
className="mx-auto"
|
className="mx-auto"
|
||||||
/>
|
/>
|
||||||
</Section>
|
</Section>
|
||||||
<Hr className=" mb-[32px] mt-[0px] h-[1px]" />
|
</Section>
|
||||||
<Section className="px-[28px]">{children}</Section>
|
<Section className="px-[28px]">{children}</Section>
|
||||||
<Hr className=" mt-[32px] mb-[0px] h-[1px]" />
|
<Hr className=" mt-[32px] mb-[0px] h-[1px]" />
|
||||||
<Section className="px-[24px] text-center">
|
<Section className="px-[24px] text-center">
|
||||||
<Text className="text-gray-500 text-[12px]">
|
<Text className="text-gray-500 text-[12px]">
|
||||||
Email sent via{" "}
|
Email sent via{" "}
|
||||||
<Link href={siteUrl} className="text-slate-700 underline decoration-slate-700">
|
<Link href={siteUrl} className="text-slate-700 no-underline">
|
||||||
Infisical
|
Infisical
|
||||||
</Link>
|
</Link>
|
||||||
</Text>
|
</Text>
|
||||||
|
@@ -1,15 +0,0 @@
|
|||||||
import { Link } from "@react-email/components";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
href: string;
|
|
||||||
children: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const BaseLink = ({ href, children }: Props) => {
|
|
||||||
return (
|
|
||||||
<Link href={href} className="text-slate-700 underline decoration-slate-700">
|
|
||||||
{children}
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
};
|
|
@@ -1,8 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface EmailMfaTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface EmailMfaTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
code: string;
|
code: string;
|
||||||
@@ -26,7 +25,11 @@ export const EmailMfaTemplate = ({ code, siteUrl, isCloud }: EmailMfaTemplatePro
|
|||||||
<strong>Not you?</strong>{" "}
|
<strong>Not you?</strong>{" "}
|
||||||
{isCloud ? (
|
{isCloud ? (
|
||||||
<>
|
<>
|
||||||
Contact us at <BaseLink href="mailto:support@infisical.com">support@infisical.com</BaseLink> immediately
|
Contact us at{" "}
|
||||||
|
<Link href="mailto:support@infisical.com" className="text-slate-700 no-underline">
|
||||||
|
support@infisical.com
|
||||||
|
</Link>{" "}
|
||||||
|
immediately
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
"Contact your administrator immediately"
|
"Contact your administrator immediately"
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface EmailVerificationTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface EmailVerificationTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
code: string;
|
code: string;
|
||||||
@@ -30,7 +29,10 @@ export const EmailVerificationTemplate = ({ code, siteUrl, isCloud }: EmailVerif
|
|||||||
<strong>Questions about Infisical?</strong>{" "}
|
<strong>Questions about Infisical?</strong>{" "}
|
||||||
{isCloud ? (
|
{isCloud ? (
|
||||||
<>
|
<>
|
||||||
Email us at <BaseLink href="mailto:support@infisical.com">support@infisical.com</BaseLink>
|
Email us at{" "}
|
||||||
|
<Link href="mailto:support@infisical.com" className="text-slate-700 no-underline">
|
||||||
|
support@infisical.com
|
||||||
|
</Link>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
"Contact your administrator"
|
"Contact your administrator"
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface ExternalImportFailedTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface ExternalImportFailedTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
error: string;
|
error: string;
|
||||||
@@ -22,9 +21,12 @@ export const ExternalImportFailedTemplate = ({ error, siteUrl, provider }: Exter
|
|||||||
</Text>
|
</Text>
|
||||||
<Text className="text-black text-[14px] leading-[24px]">
|
<Text className="text-black text-[14px] leading-[24px]">
|
||||||
If your issue persists, you can contact the Infisical team at{" "}
|
If your issue persists, you can contact the Infisical team at{" "}
|
||||||
<BaseLink href="mailto:support@infisical.com">support@infisical.com</BaseLink>.
|
<Link href="mailto:support@infisical.com" className="text-slate-700 no-underline">
|
||||||
|
support@infisical.com
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
</Text>
|
</Text>
|
||||||
<Text className="text-[14px] text-red-600 leading-[24px]">
|
<Text className="text-[14px] text-red-500 leading-[24px]">
|
||||||
<strong>Error:</strong> "{error}"
|
<strong>Error:</strong> "{error}"
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
|
|
||||||
interface IntegrationSyncFailedTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface IntegrationSyncFailedTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
@@ -31,7 +30,7 @@ export const IntegrationSyncFailedTemplate = ({
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
<strong>{count}</strong> integration(s) failed to sync
|
<strong>{count}</strong> integration(s) failed to sync
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[26px] pb-[4px] text-[14px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[26px] pb-[4px] text-[14px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<strong>Project</strong>
|
<strong>Project</strong>
|
||||||
<Text className="text-[14px] mt-[4px]">{projectName}</Text>
|
<Text className="text-[14px] mt-[4px]">{projectName}</Text>
|
||||||
<strong>Environment</strong>
|
<strong>Environment</strong>
|
||||||
@@ -39,10 +38,15 @@ export const IntegrationSyncFailedTemplate = ({
|
|||||||
<strong>Secret Path</strong>
|
<strong>Secret Path</strong>
|
||||||
<Text className="text-[14px] mt-[4px]">{secretPath}</Text>
|
<Text className="text-[14px] mt-[4px]">{secretPath}</Text>
|
||||||
<strong className="text-black">Failure Reason:</strong>
|
<strong className="text-black">Failure Reason:</strong>
|
||||||
<Text className="text-[14px] mt-[4px] text-red-600 leading-[24px]">"{syncMessage}"</Text>
|
<Text className="text-[14px] mt-[4px] text-red-500 leading-[24px]">"{syncMessage}"</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={integrationUrl}>View Integrations</BaseButton>
|
<Button
|
||||||
|
href={integrationUrl}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
View Integrations
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface NewDeviceLoginTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface NewDeviceLoginTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
email: string;
|
email: string;
|
||||||
@@ -43,7 +42,9 @@ export const NewDeviceLoginTemplate = ({
|
|||||||
<Text className="mb-[0px]">
|
<Text className="mb-[0px]">
|
||||||
If you believe that this login is suspicious, please contact{" "}
|
If you believe that this login is suspicious, please contact{" "}
|
||||||
{isCloud ? (
|
{isCloud ? (
|
||||||
<BaseLink href="mailto:support@infisical.com">support@infisical.com</BaseLink>
|
<Link href="mailto:support@infisical.com" className="text-slate-700 no-underline">
|
||||||
|
support@infisical.com
|
||||||
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
"your administrator"
|
"your administrator"
|
||||||
)}{" "}
|
)}{" "}
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface OrgAdminBreakglassAccessTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface OrgAdminBreakglassAccessTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
email: string;
|
email: string;
|
||||||
@@ -36,7 +35,10 @@ export const OrgAdminBreakglassAccessTemplate = ({
|
|||||||
<Text className="text-[14px] mt-[4px]">{userAgent}</Text>
|
<Text className="text-[14px] mt-[4px]">{userAgent}</Text>
|
||||||
<Text className="text-[14px]">
|
<Text className="text-[14px]">
|
||||||
If you'd like to disable Admin SSO Bypass, please visit{" "}
|
If you'd like to disable Admin SSO Bypass, please visit{" "}
|
||||||
<BaseLink href={`${siteUrl}/organization/settings`}>Organization Security Settings</BaseLink>.
|
<Link href={`${siteUrl}/organization/settings`} className="text-slate-700 no-underline">
|
||||||
|
Organization Security Settings
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
|
@@ -2,7 +2,6 @@ import { Heading, Section, Text } from "@react-email/components";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface OrgAdminProjectGrantAccessTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview"> {
|
interface OrgAdminProjectGrantAccessTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview"> {
|
||||||
email: string;
|
email: string;
|
||||||
@@ -25,8 +24,8 @@ export const OrgAdminProjectGrantAccessTemplate = ({
|
|||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mt-[36px] pt-[24px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[24px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-[14px] mt-[4px]">
|
<Text className="text-[14px] mt-[4px]">
|
||||||
The organization admin <BaseLink href={`mailto:${email}`}>{email}</BaseLink> has self-issued direct access to
|
The organization admin <strong>{email}</strong> has self-issued direct access to the project{" "}
|
||||||
the project <strong>{projectName}</strong>.
|
<strong>{projectName}</strong>.
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface OrganizationInvitationTemplateProps extends Omit<BaseEmailWrapperProps, "preview" | "title"> {
|
interface OrganizationInvitationTemplateProps extends Omit<BaseEmailWrapperProps, "preview" | "title"> {
|
||||||
metadata?: string;
|
metadata?: string;
|
||||||
@@ -38,13 +36,15 @@ export const OrganizationInvitationTemplate = ({
|
|||||||
<br />
|
<br />
|
||||||
<strong>{organizationName}</strong> on <strong>Infisical</strong>
|
<strong>{organizationName}</strong> on <strong>Infisical</strong>
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] pb-[8px] border text-center border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[12px] pb-[8px] border text-center border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-black text-[14px] leading-[24px]">
|
<Text className="text-black text-[14px] leading-[24px]">
|
||||||
{inviterFirstName && inviterUsername ? (
|
{inviterFirstName && inviterUsername ? (
|
||||||
<>
|
<>
|
||||||
<strong>{inviterFirstName}</strong> (
|
<strong>{inviterFirstName}</strong> (
|
||||||
<BaseLink href={`mailto:${inviterUsername}`}>{inviterUsername}</BaseLink>) has invited you to collaborate
|
<Link href={`mailto:${inviterUsername}`} className="text-slate-700 no-underline">
|
||||||
on <strong>{organizationName}</strong>.
|
{inviterUsername}
|
||||||
|
</Link>
|
||||||
|
) has invited you to collaborate on <strong>{organizationName}</strong>.
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
@@ -53,12 +53,13 @@ export const OrganizationInvitationTemplate = ({
|
|||||||
)}
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton
|
<Button
|
||||||
href={`${callback_url}?token=${token}${metadata ? `&metadata=${metadata}` : ""}&to=${encodeURIComponent(email)}&organization_id=${organizationId}`}
|
href={`${callback_url}?token=${token}${metadata ? `&metadata=${metadata}` : ""}&to=${encodeURIComponent(email)}&organization_id=${organizationId}`}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
>
|
>
|
||||||
Accept Invite
|
Accept Invite
|
||||||
</BaseButton>
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="mt-[24px] bg-gray-50 pt-[2px] pb-[16px] border border-solid border-gray-200 px-[24px] rounded-md text-gray-800">
|
<Section className="mt-[24px] bg-gray-50 pt-[2px] pb-[16px] border border-solid border-gray-200 px-[24px] rounded-md text-gray-800">
|
||||||
<Text className="mb-[0px]">
|
<Text className="mb-[0px]">
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface PasswordResetTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface PasswordResetTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
email: string;
|
email: string;
|
||||||
@@ -22,13 +20,16 @@ export const PasswordResetTemplate = ({ email, isCloud, siteUrl, callback_url, t
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
<strong>Account Recovery</strong>
|
<strong>Account Recovery</strong>
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-[14px]">A password reset was requested for your Infisical account.</Text>
|
<Text className="text-[14px]">A password reset was requested for your Infisical account.</Text>
|
||||||
<Text className="text-[14px]">
|
<Text className="text-[14px]">
|
||||||
If you did not initiate this request, please contact{" "}
|
If you did not initiate this request, please contact{" "}
|
||||||
{isCloud ? (
|
{isCloud ? (
|
||||||
<>
|
<>
|
||||||
us immediately at <BaseLink href="mailto:support@infisical.com">support@infisical.com</BaseLink>
|
us immediately at{" "}
|
||||||
|
<Link href="mailto:support@infisical.com" className="text-slate-700 no-underline">
|
||||||
|
support@infisical.com
|
||||||
|
</Link>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
"your administrator immediately"
|
"your administrator immediately"
|
||||||
@@ -36,8 +37,13 @@ export const PasswordResetTemplate = ({ email, isCloud, siteUrl, callback_url, t
|
|||||||
.
|
.
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={`${callback_url}?token=${token}&to=${encodeURIComponent(email)}`}>Reset Password</BaseButton>
|
<Button
|
||||||
|
href={`${callback_url}?token=${token}&to=${encodeURIComponent(email)}`}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
Reset Password
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
import { Button, Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseLink } from "@app/services/smtp/emails/BaseLink";
|
|
||||||
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
|
|
||||||
interface PasswordSetupTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface PasswordSetupTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
@@ -18,16 +16,19 @@ export const PasswordSetupTemplate = ({ email, isCloud, siteUrl, callback_url, t
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
<strong>Password Setup</strong>
|
<strong>Password Setup</strong>
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-[14px]">Someone requested to set up a password for your Infisical account.</Text>
|
<Text className="text-[14px]">Someone requested to set up a password for your Infisical account.</Text>
|
||||||
<Text className="text-[14px] text-red-600">
|
<Text className="text-[14px] text-red-500">
|
||||||
Make sure you are already logged in to Infisical in the current browser before clicking the link below.
|
Make sure you are already logged in to Infisical in the current browser before clicking the link below.
|
||||||
</Text>
|
</Text>
|
||||||
<Text className="text-[14px]">
|
<Text className="text-[14px]">
|
||||||
If you did not initiate this request, please contact{" "}
|
If you did not initiate this request, please contact{" "}
|
||||||
{isCloud ? (
|
{isCloud ? (
|
||||||
<>
|
<>
|
||||||
us immediately at <BaseLink href="mailto:support@infisical.com">support@infisical.com</BaseLink>
|
us immediately at{" "}
|
||||||
|
<Link href="mailto:support@infisical.com" className="text-slate-700 no-underline">
|
||||||
|
support@infisical.com
|
||||||
|
</Link>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
"your administrator immediately"
|
"your administrator immediately"
|
||||||
@@ -35,7 +36,7 @@ export const PasswordSetupTemplate = ({ email, isCloud, siteUrl, callback_url, t
|
|||||||
.
|
.
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<Button
|
<Button
|
||||||
href={`${callback_url}?token=${token}&to=${encodeURIComponent(email)}`}
|
href={`${callback_url}?token=${token}&to=${encodeURIComponent(email)}`}
|
||||||
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface ProjectAccessRequestTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface ProjectAccessRequestTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
projectName: string;
|
projectName: string;
|
||||||
@@ -32,17 +30,26 @@ export const ProjectAccessRequestTemplate = ({
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
A user has requested access to the project <strong>{projectName}</strong>
|
A user has requested access to the project <strong>{projectName}</strong>
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-black text-[14px] leading-[24px]">
|
<Text className="text-black text-[14px] leading-[24px]">
|
||||||
<strong>{requesterName}</strong> (<BaseLink href={`mailto:${requesterEmail}`}>{requesterEmail}</BaseLink>) has
|
<strong>{requesterName}</strong> (
|
||||||
requested access to the project <strong>{projectName}</strong> in the organization <strong>{orgName}</strong>.
|
<Link href={`mailto:${requesterEmail}`} className="text-slate-700 no-underline">
|
||||||
|
{requesterEmail}
|
||||||
|
</Link>
|
||||||
|
) has requested access to the project <strong>{projectName}</strong> in the organization{" "}
|
||||||
|
<strong>{orgName}</strong>.
|
||||||
</Text>
|
</Text>
|
||||||
<Text className="text-[14px] text-slate-700 leading-[24px]">
|
<Text className="text-[14px] text-slate-700 leading-[24px]">
|
||||||
<strong className="text-black">User note:</strong> "{note}"
|
<strong className="text-black">User note:</strong> "{note}"
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={callback_url}>Grant Access</BaseButton>
|
<Button
|
||||||
|
href={callback_url}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
Grant Access
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
|
|
||||||
interface ProjectInvitationTemplateProps extends Omit<BaseEmailWrapperProps, "preview" | "title"> {
|
interface ProjectInvitationTemplateProps extends Omit<BaseEmailWrapperProps, "preview" | "title"> {
|
||||||
@@ -19,13 +18,18 @@ export const ProjectInvitationTemplate = ({ callback_url, workspaceName, siteUrl
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
You've been invited to join a project on Infisical
|
You've been invited to join a project on Infisical
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] pb-[8px] border text-center border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[12px] pb-[8px] border text-center border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-black text-[14px] leading-[24px]">
|
<Text className="text-black text-[14px] leading-[24px]">
|
||||||
You've been invited to join the project <strong>{workspaceName}</strong>.
|
You've been invited to join the project <strong>{workspaceName}</strong>.
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={callback_url}>Join Project</BaseButton>
|
<Button
|
||||||
|
href={callback_url}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
Join Project
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="mt-[24px] bg-gray-50 pt-[2px] pb-[16px] border border-solid border-gray-200 px-[24px] rounded-md text-gray-800">
|
<Section className="mt-[24px] bg-gray-50 pt-[2px] pb-[16px] border border-solid border-gray-200 px-[24px] rounded-md text-gray-800">
|
||||||
<Text className="mb-[0px]">
|
<Text className="mb-[0px]">
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
|
|
||||||
interface ScimUserProvisionedTemplateProps extends Omit<BaseEmailWrapperProps, "preview" | "title"> {
|
interface ScimUserProvisionedTemplateProps extends Omit<BaseEmailWrapperProps, "preview" | "title"> {
|
||||||
@@ -25,13 +24,18 @@ export const ScimUserProvisionedTemplate = ({
|
|||||||
<br />
|
<br />
|
||||||
<strong>{organizationName}</strong> on <strong>Infisical</strong>
|
<strong>{organizationName}</strong> on <strong>Infisical</strong>
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] pb-[8px] border text-center border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[12px] pb-[8px] border text-center border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-black text-[14px] leading-[24px]">
|
<Text className="text-black text-[14px] leading-[24px]">
|
||||||
You've been invited to collaborate on <strong>{organizationName}</strong>.
|
You've been invited to collaborate on <strong>{organizationName}</strong>.
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={callback_url}>Accept Invite</BaseButton>
|
<Button
|
||||||
|
href={callback_url}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
Accept Invite
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="mt-[24px] bg-gray-50 pt-[2px] pb-[16px] border border-solid border-gray-200 px-[24px] rounded-md text-gray-800">
|
<Section className="mt-[24px] bg-gray-50 pt-[2px] pb-[16px] border border-solid border-gray-200 px-[24px] rounded-md text-gray-800">
|
||||||
<Text className="mb-[0px]">
|
<Text className="mb-[0px]">
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface SecretApprovalRequestBypassedTemplateProps
|
interface SecretApprovalRequestBypassedTemplateProps
|
||||||
extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
@@ -37,10 +35,13 @@ export const SecretApprovalRequestBypassedTemplate = ({
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
A secret approval request has been bypassed in the project <strong>{projectName}</strong>
|
A secret approval request has been bypassed in the project <strong>{projectName}</strong>
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-black text-[14px] leading-[24px]">
|
<Text className="text-black text-[14px] leading-[24px]">
|
||||||
<strong>{requesterFullName}</strong> (<BaseLink href={`mailto:${requesterEmail}`}>{requesterEmail}</BaseLink>)
|
<strong>{requesterFullName}</strong> (
|
||||||
has {requestType === "change" ? "merged" : "accessed"} a secret {requestType === "change" ? "to" : "in"}{" "}
|
<Link href={`mailto:${requesterEmail}`} className="text-slate-700 no-underline">
|
||||||
|
{requesterEmail}
|
||||||
|
</Link>
|
||||||
|
) has {requestType === "change" ? "merged" : "accessed"} a secret {requestType === "change" ? "to" : "in"}{" "}
|
||||||
<strong>{secretPath}</strong> in the <strong>{environment}</strong> environment without obtaining the required
|
<strong>{secretPath}</strong> in the <strong>{environment}</strong> environment without obtaining the required
|
||||||
approval.
|
approval.
|
||||||
</Text>
|
</Text>
|
||||||
@@ -49,8 +50,13 @@ export const SecretApprovalRequestBypassedTemplate = ({
|
|||||||
{bypassReason}"
|
{bypassReason}"
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={approvalUrl}>Review Bypass</BaseButton>
|
<Button
|
||||||
|
href={approvalUrl}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
Review Bypass
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
|
|
||||||
interface SecretApprovalRequestNeedsReviewTemplateProps
|
interface SecretApprovalRequestNeedsReviewTemplateProps
|
||||||
@@ -28,15 +27,20 @@ export const SecretApprovalRequestNeedsReviewTemplate = ({
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
A secret approval request for the project <strong>{projectName}</strong> requires review
|
A secret approval request for the project <strong>{projectName}</strong> requires review
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-[14px]">Hello {firstName},</Text>
|
<Text className="text-[14px]">Hello {firstName},</Text>
|
||||||
<Text className="text-black text-[14px] leading-[24px]">
|
<Text className="text-black text-[14px] leading-[24px]">
|
||||||
You have a new secret change request pending your review for the project <strong>{projectName}</strong> in the
|
You have a new secret change request pending your review for the project <strong>{projectName}</strong> in the
|
||||||
organization <strong>{organizationName}</strong>.
|
organization <strong>{organizationName}</strong>.
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={approvalUrl}>Review Changes</BaseButton>
|
<Button
|
||||||
|
href={approvalUrl}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
Review Changes
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface SecretLeakIncidentTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface SecretLeakIncidentTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
numberOfSecrets: number;
|
numberOfSecrets: number;
|
||||||
@@ -26,7 +24,7 @@ export const SecretLeakIncidentTemplate = ({
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
Infisical has uncovered <strong>{numberOfSecrets}</strong> secret(s) from a recent commit
|
Infisical has uncovered <strong>{numberOfSecrets}</strong> secret(s) from a recent commit
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[8px] pb-[8px] text-[14px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[8px] pb-[8px] text-[14px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-[14px]">
|
<Text className="text-[14px]">
|
||||||
You are receiving this notification because one or more leaked secrets have been detected in a recent commit
|
You are receiving this notification because one or more leaked secrets have been detected in a recent commit
|
||||||
{(pusher_email || pusher_name) && (
|
{(pusher_email || pusher_name) && (
|
||||||
@@ -35,7 +33,11 @@ export const SecretLeakIncidentTemplate = ({
|
|||||||
pushed by <strong>{pusher_name ?? "Unknown Pusher"}</strong>{" "}
|
pushed by <strong>{pusher_name ?? "Unknown Pusher"}</strong>{" "}
|
||||||
{pusher_email && (
|
{pusher_email && (
|
||||||
<>
|
<>
|
||||||
(<BaseLink href={`mailto:${pusher_email}`}>{pusher_email}</BaseLink>)
|
(
|
||||||
|
<Link href={`mailto:${pusher_email}`} className="text-slate-700 no-underline">
|
||||||
|
{pusher_email}
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
@@ -47,16 +49,24 @@ export const SecretLeakIncidentTemplate = ({
|
|||||||
a comment in the given programming language. This will prevent future notifications from being sent out for
|
a comment in the given programming language. This will prevent future notifications from being sent out for
|
||||||
these secrets.
|
these secrets.
|
||||||
</Text>
|
</Text>
|
||||||
<Text className="text-[14px] text-red-600">
|
<Text className="text-[14px] text-red-500">
|
||||||
If these are production secrets, please rotate them immediately.
|
If these are production secrets, please rotate them immediately.
|
||||||
</Text>
|
</Text>
|
||||||
<Text className="text-[14px]">
|
<Text className="text-[14px]">
|
||||||
Once you have taken action, be sure to update the status of the risk in the{" "}
|
Once you have taken action, be sure to update the status of the risk in the{" "}
|
||||||
<BaseLink href={`${siteUrl}/organization/secret-scanning`}>Infisical Dashboard</BaseLink>.
|
<Link href={`${siteUrl}/organization/secret-scanning`} className="text-slate-700 no-underline">
|
||||||
|
Infisical Dashboard
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={`${siteUrl}/organization/secret-scanning`}>View Leaked Secrets</BaseButton>
|
<Button
|
||||||
|
href={`${siteUrl}/organization/secret-scanning`}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
View Leaked Secrets
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
|
|
||||||
interface SecretRequestCompletedTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface SecretRequestCompletedTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
@@ -21,7 +20,7 @@ export const SecretRequestCompletedTemplate = ({
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
<strong>A secret has been shared with you</strong>
|
<strong>A secret has been shared with you</strong>
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] text-center pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[12px] text-center pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-[14px]">
|
<Text className="text-[14px]">
|
||||||
{respondentUsername ? <strong>{respondentUsername}</strong> : "Someone"} shared a secret{" "}
|
{respondentUsername ? <strong>{respondentUsername}</strong> : "Someone"} shared a secret{" "}
|
||||||
{name && (
|
{name && (
|
||||||
@@ -32,8 +31,13 @@ export const SecretRequestCompletedTemplate = ({
|
|||||||
with you.
|
with you.
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={secretRequestUrl}>View Secret</BaseButton>
|
<Button
|
||||||
|
href={secretRequestUrl}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
View Secret
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
|
|
||||||
interface SecretRotationFailedTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface SecretRotationFailedTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
@@ -29,7 +28,7 @@ export const SecretRotationFailedTemplate = ({
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
Your <strong>{rotationType}</strong> rotation <strong>{rotationName}</strong> failed to rotate
|
Your <strong>{rotationType}</strong> rotation <strong>{rotationName}</strong> failed to rotate
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[26px] pb-[4px] text-[14px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[26px] pb-[4px] text-[14px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<strong>Name</strong>
|
<strong>Name</strong>
|
||||||
<Text className="text-[14px] mt-[4px]">{rotationName}</Text>
|
<Text className="text-[14px] mt-[4px]">{rotationName}</Text>
|
||||||
<strong>Type</strong>
|
<strong>Type</strong>
|
||||||
@@ -41,12 +40,15 @@ export const SecretRotationFailedTemplate = ({
|
|||||||
<strong>Secret Path</strong>
|
<strong>Secret Path</strong>
|
||||||
<Text className="text-[14px] mt-[4px]">{secretPath}</Text>
|
<Text className="text-[14px] mt-[4px]">{secretPath}</Text>
|
||||||
<strong>Reason:</strong>
|
<strong>Reason:</strong>
|
||||||
<Text className="text-[14px] text-red-600 mt-[4px]">{content}</Text>
|
<Text className="text-[14px] text-red-500 mt-[4px]">{content}</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={`${rotationUrl}?search=${rotationName}&secretPath=${secretPath}`}>
|
<Button
|
||||||
|
href={`${rotationUrl}?search=${rotationName}&secretPath=${secretPath}`}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
View in Infisical
|
View in Infisical
|
||||||
</BaseButton>
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
|
|
||||||
interface SecretScanningScanFailedTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface SecretScanningScanFailedTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
@@ -31,7 +30,7 @@ export const SecretScanningScanFailedTemplate = ({
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
Infisical encountered an error while attempting to scan the resource <strong>{resourceName}</strong>
|
Infisical encountered an error while attempting to scan the resource <strong>{resourceName}</strong>
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[26px] pb-[4px] text-[14px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[26px] pb-[4px] text-[14px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<strong>Resource</strong>
|
<strong>Resource</strong>
|
||||||
<Text className="text-[14px] mt-[4px]">{resourceName}</Text>
|
<Text className="text-[14px] mt-[4px]">{resourceName}</Text>
|
||||||
<strong>Data Source</strong>
|
<strong>Data Source</strong>
|
||||||
@@ -41,10 +40,15 @@ export const SecretScanningScanFailedTemplate = ({
|
|||||||
<strong>Timestamp</strong>
|
<strong>Timestamp</strong>
|
||||||
<Text className="text-[14px] mt-[4px]">{timestamp}</Text>
|
<Text className="text-[14px] mt-[4px]">{timestamp}</Text>
|
||||||
<strong>Error</strong>
|
<strong>Error</strong>
|
||||||
<Text className="text-[14px] text-red-600 mt-[4px]">{errorMessage}</Text>
|
<Text className="text-[14px] text-red-500 mt-[4px]">{errorMessage}</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={url}>View in Infisical</BaseButton>
|
<Button
|
||||||
|
href={url}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
View in Infisical
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface SecretScanningSecretsDetectedTemplateProps
|
interface SecretScanningSecretsDetectedTemplateProps
|
||||||
extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
@@ -34,7 +32,7 @@ export const SecretScanningSecretsDetectedTemplate = ({
|
|||||||
Infisical has uncovered <strong>{numberOfSecrets}</strong> secret(s)
|
Infisical has uncovered <strong>{numberOfSecrets}</strong> secret(s)
|
||||||
{isDiffScan ? " from a recent commit to" : " in"} <strong>{resourceName}</strong>
|
{isDiffScan ? " from a recent commit to" : " in"} <strong>{resourceName}</strong>
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[8px] pb-[8px] text-[14px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[8px] pb-[8px] text-[14px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-[14px]">
|
<Text className="text-[14px]">
|
||||||
You are receiving this notification because one or more leaked secrets have been detected
|
You are receiving this notification because one or more leaked secrets have been detected
|
||||||
{isDiffScan && " in a recent commit"}
|
{isDiffScan && " in a recent commit"}
|
||||||
@@ -45,7 +43,11 @@ export const SecretScanningSecretsDetectedTemplate = ({
|
|||||||
pushed by <strong>{authorName ?? "Unknown Pusher"}</strong>{" "}
|
pushed by <strong>{authorName ?? "Unknown Pusher"}</strong>{" "}
|
||||||
{authorEmail && (
|
{authorEmail && (
|
||||||
<>
|
<>
|
||||||
(<BaseLink href={`mailto:${authorEmail}`}>{authorEmail}</BaseLink>)
|
(
|
||||||
|
<Link href={`mailto:${authorEmail}`} className="text-slate-700 no-underline">
|
||||||
|
{authorEmail}
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
@@ -63,16 +65,24 @@ export const SecretScanningSecretsDetectedTemplate = ({
|
|||||||
a comment in the given programming language. This will prevent future notifications from being sent out for
|
a comment in the given programming language. This will prevent future notifications from being sent out for
|
||||||
these secrets.
|
these secrets.
|
||||||
</Text>
|
</Text>
|
||||||
<Text className="text-[14px] text-red-600">
|
<Text className="text-[14px] text-red-500">
|
||||||
If these are production secrets, please rotate them immediately.
|
If these are production secrets, please rotate them immediately.
|
||||||
</Text>
|
</Text>
|
||||||
<Text className="text-[14px]">
|
<Text className="text-[14px]">
|
||||||
Once you have taken action, be sure to update the finding status in the{" "}
|
Once you have taken action, be sure to update the finding status in the{" "}
|
||||||
<BaseLink href={url}>Infisical Dashboard</BaseLink>.
|
<Link href={url} className="text-slate-700 no-underline">
|
||||||
|
Infisical Dashboard
|
||||||
|
</Link>
|
||||||
|
.
|
||||||
</Text>
|
</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={url}>View Leaked Secrets</BaseButton>
|
<Button
|
||||||
|
href={url}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
View Leaked Secrets
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
|
|
||||||
interface SecretSyncFailedTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface SecretSyncFailedTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
@@ -29,7 +28,7 @@ export const SecretSyncFailedTemplate = ({
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
Your <strong>{syncDestination}</strong> sync <strong>{syncName}</strong> failed to complete
|
Your <strong>{syncDestination}</strong> sync <strong>{syncName}</strong> failed to complete
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[26px] pb-[4px] text-[14px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[26px] pb-[4px] text-[14px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<strong>Name</strong>
|
<strong>Name</strong>
|
||||||
<Text className="text-[14px] mt-[4px]">{syncName}</Text>
|
<Text className="text-[14px] mt-[4px]">{syncName}</Text>
|
||||||
<strong>Destination</strong>
|
<strong>Destination</strong>
|
||||||
@@ -51,12 +50,17 @@ export const SecretSyncFailedTemplate = ({
|
|||||||
{failureMessage && (
|
{failureMessage && (
|
||||||
<>
|
<>
|
||||||
<strong>Reason:</strong>
|
<strong>Reason:</strong>
|
||||||
<Text className="text-[14px] text-red-600 mt-[4px]">{failureMessage}</Text>
|
<Text className="text-[14px] text-red-500 mt-[4px]">{failureMessage}</Text>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={syncUrl}>View in Infisical</BaseButton>
|
<Button
|
||||||
|
href={syncUrl}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
View in Infisical
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
|
|
||||||
interface ServiceTokenExpiryNoticeTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface ServiceTokenExpiryNoticeTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
@@ -25,15 +24,20 @@ export const ServiceTokenExpiryNoticeTemplate = ({
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
<strong>Service token expiry notice</strong>
|
<strong>Service token expiry notice</strong>
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-[14px]">
|
<Text className="text-[14px]">
|
||||||
Your service token <strong>{tokenName}</strong> for the project <strong>{projectName}</strong> will expire
|
Your service token <strong>{tokenName}</strong> for the project <strong>{projectName}</strong> will expire
|
||||||
within 24 hours.
|
within 24 hours.
|
||||||
</Text>
|
</Text>
|
||||||
<Text>If this token is still needed for your workflow, please create a new one before it expires.</Text>
|
<Text>If this token is still needed for your workflow, please create a new one before it expires.</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={url}>Create New Token</BaseButton>
|
<Button
|
||||||
|
href={url}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
Create New Token
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Heading, Link, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
import { BaseLink } from "./BaseLink";
|
|
||||||
|
|
||||||
interface SignupEmailVerificationTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface SignupEmailVerificationTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
code: string;
|
code: string;
|
||||||
@@ -30,7 +29,10 @@ export const SignupEmailVerificationTemplate = ({ code, siteUrl, isCloud }: Sign
|
|||||||
<strong>Questions about setting up Infisical?</strong>{" "}
|
<strong>Questions about setting up Infisical?</strong>{" "}
|
||||||
{isCloud ? (
|
{isCloud ? (
|
||||||
<>
|
<>
|
||||||
Email us at <BaseLink href="mailto:support@infisical.com">support@infisical.com</BaseLink>
|
Email us at{" "}
|
||||||
|
<Link href="mailto:support@infisical.com" className="text-slate-700 no-underline">
|
||||||
|
support@infisical.com
|
||||||
|
</Link>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
"Contact your administrator"
|
"Contact your administrator"
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { Heading, Section, Text } from "@react-email/components";
|
import { Button, Heading, Section, Text } from "@react-email/components";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { BaseButton } from "./BaseButton";
|
|
||||||
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
|
||||||
|
|
||||||
interface UnlockAccountTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
interface UnlockAccountTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
|
||||||
@@ -19,14 +18,19 @@ export const UnlockAccountTemplate = ({ token, siteUrl, callback_url }: UnlockAc
|
|||||||
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
<Heading className="text-black text-[18px] leading-[28px] text-center font-normal p-0 mx-0">
|
||||||
<strong>Unlock your Infisical account</strong>
|
<strong>Unlock your Infisical account</strong>
|
||||||
</Heading>
|
</Heading>
|
||||||
<Section className="px-[24px] mb-[28px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
<Section className="px-[24px] mt-[36px] pt-[12px] pb-[8px] border border-solid border-gray-200 rounded-md bg-gray-50">
|
||||||
<Text className="text-[14px]">
|
<Text className="text-[14px]">
|
||||||
Your account has been temporarily locked due to multiple failed login attempts.
|
Your account has been temporarily locked due to multiple failed login attempts.
|
||||||
</Text>
|
</Text>
|
||||||
<Text>If these attempts were not made by you, reset your password immediately.</Text>
|
<Text>If these attempts were not made by you, reset your password immediately.</Text>
|
||||||
</Section>
|
</Section>
|
||||||
<Section className="text-center">
|
<Section className="text-center mt-[28px]">
|
||||||
<BaseButton href={`${callback_url}?token=${token}`}>Unlock Account</BaseButton>
|
<Button
|
||||||
|
href={`${callback_url}?token=${token}`}
|
||||||
|
className="rounded-md p-3 px-[28px] my-[8px] text-center text-[16px] bg-[#EBF852] border-solid border border-[#d1e309] text-black font-medium"
|
||||||
|
>
|
||||||
|
Unlock Account
|
||||||
|
</Button>
|
||||||
</Section>
|
</Section>
|
||||||
</BaseEmailWrapper>
|
</BaseEmailWrapper>
|
||||||
);
|
);
|
||||||
|
@@ -105,13 +105,10 @@ The templates hold an array of templates that will be rendered and injected into
|
|||||||
|
|
||||||
|
|
||||||
### Authentication
|
### Authentication
|
||||||
The Infisical Agent Injector supports Machine Identity [Kubernetes Auth](/documentation/platform/identities/kubernetes-auth) and [LDAP Auth](/documentation/platform/identities/ldap-auth) authentication.
|
The Infisical Agent Injector only supports Machine Identity [Kubernetes Auth](/documentation/platform/identities/kubernetes-auth) authentication at the moment.
|
||||||
|
|
||||||
|
|
||||||
<AccordionGroup>
|
|
||||||
<Accordion title="Kubernetes Auth">
|
|
||||||
|
|
||||||
To configure Kubernetes Auth, you need to set the `auth.type` field to `kubernetes` and set the `auth.config.identity-id` to the ID of the machine identity you wish to use for authentication.
|
To configure Kubernetes Auth, you need to set the `auth.type` field to `kubernetes` and set the `auth.config.identity-id` to the ID of the machine identity you wish to use for authentication.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
auth:
|
auth:
|
||||||
type: "kubernetes"
|
type: "kubernetes"
|
||||||
@@ -147,52 +144,6 @@ The Infisical Agent Injector supports Machine Identity [Kubernetes Auth](/docume
|
|||||||
kubectl apply -f config-map.yaml
|
kubectl apply -f config-map.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
</Accordion>
|
|
||||||
<Accordion title="LDAP Auth">
|
|
||||||
To configure LDAP Auth, you need to set the `auth.type` field to `ldap-auth` and set the `auth.config.identity-id` to the ID of the machine identity you wish to use for authentication. Configure the `auth.config.username` and `auth.config.password` to the username and password of the LDAP user to authenticate with.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
auth:
|
|
||||||
type: "ldap-auth"
|
|
||||||
config:
|
|
||||||
identity-id: "<your-infisical-machine-identity-id>"
|
|
||||||
username: "<your-ldap-username>"
|
|
||||||
password: "<your-ldap-password>"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example ConfigMap
|
|
||||||
```yaml config-map.yaml
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: demo-config-map
|
|
||||||
data:
|
|
||||||
config.yaml: |
|
|
||||||
infisical:
|
|
||||||
address: "https://app.infisical.com"
|
|
||||||
auth:
|
|
||||||
type: "ldap-auth"
|
|
||||||
config:
|
|
||||||
identity-id: "<your-infisical-machine-identity-id>"
|
|
||||||
username: "<your-ldap-username>"
|
|
||||||
password: "<your-ldap-password>"
|
|
||||||
templates:
|
|
||||||
- destination-path: "/path/to/save/secrets/file.txt"
|
|
||||||
template-content: |
|
|
||||||
{{- with secret "<your-project-id>" "dev" "/" }}
|
|
||||||
{{- range . }}
|
|
||||||
{{ .Key }}={{ .Value }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl apply -f config-map.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
</Accordion>
|
|
||||||
</AccordionGroup>
|
|
||||||
|
|
||||||
To use the config map in your pod, you will need to add the `org.infisical.com/agent-config-map` annotation to your pod's deployment. The value of the annotation is the name of the config map you created above.
|
To use the config map in your pod, you will need to add the `org.infisical.com/agent-config-map` annotation to your pod's deployment. The value of the annotation is the name of the config map you created above.
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@@ -68,6 +68,11 @@ spec:
|
|||||||
serviceAccountKeyFilePath: </path-to-service-account-key-file.json>
|
serviceAccountKeyFilePath: </path-to-service-account-key-file.json>
|
||||||
gcpIdTokenAuth:
|
gcpIdTokenAuth:
|
||||||
identityId: <machine-identity-id>
|
identityId: <machine-identity-id>
|
||||||
|
ldapAuth:
|
||||||
|
identityId: <machine-identity-id>
|
||||||
|
credentialsRef:
|
||||||
|
secretName: <secret-name> # ldap-auth-credentials
|
||||||
|
secretNamespace: <secret-namespace> # default
|
||||||
kubernetesAuth:
|
kubernetesAuth:
|
||||||
identityId: <machine-identity-id>
|
identityId: <machine-identity-id>
|
||||||
serviceAccountRef:
|
serviceAccountRef:
|
||||||
@@ -137,6 +142,7 @@ When `hostAPI` is not defined the operator fetches secrets from Infisical Cloud.
|
|||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
The lease duration at most be 1 day (24 hours). And the TTL must be less than the max TTL defined on the dynamic secret.
|
The lease duration at most be 1 day (24 hours). And the TTL must be less than the max TTL defined on the dynamic secret.
|
||||||
|
|
||||||
</Note>
|
</Note>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
@@ -300,7 +306,6 @@ The available authentication methods are `universalAuth`, `kubernetesAuth`, `aws
|
|||||||
- `autoCreateServiceAccountToken`: If set to `true`, the operator will automatically create a short-lived service account token on-demand for the service account. Defaults to `false`.
|
- `autoCreateServiceAccountToken`: If set to `true`, the operator will automatically create a short-lived service account token on-demand for the service account. Defaults to `false`.
|
||||||
- `serviceAccountTokenAudiences`: Optionally specify audience for the service account token. This field is only relevant if you have set `autoCreateServiceAccountToken` to `true`. No audience is specified by default.
|
- `serviceAccountTokenAudiences`: Optionally specify audience for the service account token. This field is only relevant if you have set `autoCreateServiceAccountToken` to `true`. No audience is specified by default.
|
||||||
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -316,7 +321,40 @@ The available authentication methods are `universalAuth`, `kubernetesAuth`, `aws
|
|||||||
```
|
```
|
||||||
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
<Accordion title="ldapAuth">
|
||||||
|
The LDAP machine identity authentication method is used to authenticate with a configured LDAP directory. [Read more about LDAP Auth](/documentation/platform/identities/ldap-auth).
|
||||||
|
|
||||||
|
Valid fields:
|
||||||
|
- `identityId`: The identity ID of the machine identity you created.
|
||||||
|
- `credentialsRef`: The name and namespace of the Kubernetes secret that stores the LDAP credentials.
|
||||||
|
- `credentialsRef.secretName`: The name of the Kubernetes secret.
|
||||||
|
- `credentialsRef.secretNamespace`: The namespace of the Kubernetes secret.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# infisical-push-secret.yaml
|
||||||
|
spec:
|
||||||
|
ldapAuth:
|
||||||
|
identityId: <machine-identity-id>
|
||||||
|
credentialsRef:
|
||||||
|
secretName: <secret-name>
|
||||||
|
secretNamespace: <secret-namespace>
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# machine-identity-credentials.yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ldap-auth-credentials
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
username: <ldap-username>
|
||||||
|
password: <ldap-password>
|
||||||
|
```
|
||||||
|
|
||||||
|
</Accordion>
|
||||||
<Accordion title="awsIamAuth">
|
<Accordion title="awsIamAuth">
|
||||||
The AWS IAM machine identity authentication method is used to authenticate with Infisical.
|
The AWS IAM machine identity authentication method is used to authenticate with Infisical.
|
||||||
[Read more about AWS IAM Auth](/documentation/platform/identities/aws-auth).
|
[Read more about AWS IAM Auth](/documentation/platform/identities/aws-auth).
|
||||||
|
@@ -70,6 +70,11 @@ Before applying the InfisicalPushSecret CRD, you need to create a Kubernetes sec
|
|||||||
serviceAccountRef:
|
serviceAccountRef:
|
||||||
name: <secret-name>
|
name: <secret-name>
|
||||||
namespace: <secret-namespace>
|
namespace: <secret-namespace>
|
||||||
|
ldapAuth:
|
||||||
|
identityId: <machine-identity-id>
|
||||||
|
credentialsRef:
|
||||||
|
secretName: <secret-name> # ldap-auth-credentials
|
||||||
|
secretNamespace: <secret-namespace> # default
|
||||||
universalAuth:
|
universalAuth:
|
||||||
credentialsRef:
|
credentialsRef:
|
||||||
secretName: <secret-name> # universal-auth-credentials
|
secretName: <secret-name> # universal-auth-credentials
|
||||||
@@ -324,7 +329,39 @@ After applying the InfisicalPushSecret CRD, you should notice that the secrets y
|
|||||||
namespace: <secret-namespace>
|
namespace: <secret-namespace>
|
||||||
```
|
```
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
<Accordion title="ldapAuth">
|
||||||
|
The LDAP machine identity authentication method is used to authenticate with a configured LDAP directory. [Read more about LDAP Auth](/documentation/platform/identities/ldap-auth).
|
||||||
|
|
||||||
|
Valid fields:
|
||||||
|
- `identityId`: The identity ID of the machine identity you created.
|
||||||
|
- `credentialsRef`: The name and namespace of the Kubernetes secret that stores the LDAP credentials.
|
||||||
|
- `credentialsRef.secretName`: The name of the Kubernetes secret.
|
||||||
|
- `credentialsRef.secretNamespace`: The namespace of the Kubernetes secret.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# infisical-push-secret.yaml
|
||||||
|
spec:
|
||||||
|
ldapAuth:
|
||||||
|
identityId: <machine-identity-id>
|
||||||
|
credentialsRef:
|
||||||
|
secretName: <secret-name>
|
||||||
|
secretNamespace: <secret-namespace>
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# machine-identity-credentials.yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ldap-auth-credentials
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
username: <ldap-username>
|
||||||
|
password: <ldap-password>
|
||||||
|
```
|
||||||
|
</Accordion>
|
||||||
<Accordion title="awsIamAuth">
|
<Accordion title="awsIamAuth">
|
||||||
The AWS IAM machine identity authentication method is used to authenticate with Infisical.
|
The AWS IAM machine identity authentication method is used to authenticate with Infisical.
|
||||||
[Read more about AWS IAM Auth](/documentation/platform/identities/aws-auth).
|
[Read more about AWS IAM Auth](/documentation/platform/identities/aws-auth).
|
||||||
|
@@ -525,49 +525,6 @@ spec:
|
|||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
@@ -747,6 +704,59 @@ spec:
|
|||||||
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
|
<Accordion title="authentication.ldapAuth">
|
||||||
|
The LDAP machine identity authentication method is used to authenticate with Infisical using the configured LDAP directory. The username and password needs to be stored in a Kubernetes secret. This block defines the reference to the name and namespace of secret that stores these credentials.
|
||||||
|
|
||||||
|
<Steps>
|
||||||
|
<Step title="Create a machine identity">
|
||||||
|
You need to create a machine identity, and give it access to the project(s) you want to interact with. You can [read more about machine identities here](/documentation/platform/identities/universal-auth).
|
||||||
|
</Step>
|
||||||
|
<Step title="Create Kubernetes secret containing machine identity credentials">
|
||||||
|
Once you have created your machine identity and added it to your project(s), you will need to create a Kubernetes secret containing the identity credentials.
|
||||||
|
To quickly create a Kubernetes secret containing the identity credentials, you can run the command below.
|
||||||
|
|
||||||
|
Make sure you replace `<your-identity-ldap-username>` with the identity LDAP username and `<your-identity-ldap-password>` with the identity LDAP password.
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
kubectl create secret generic ldap-auth-credentials --from-literal=username="<your-identity-ldap-username>" --from-literal=password="<your-identity-ldap-password>"
|
||||||
|
```
|
||||||
|
</Step>
|
||||||
|
|
||||||
|
<Step title="Add reference for the Kubernetes secret containing the identity credentials">
|
||||||
|
Once the secret is created, add the `secretName` and `secretNamespace` of the secret that was just created under `authentication.ldapAuth.credentialsRef` field in the InfisicalSecret resource.
|
||||||
|
</Step>
|
||||||
|
|
||||||
|
</Steps>
|
||||||
|
|
||||||
|
<Info>
|
||||||
|
Make sure to also populate the `secretsScope` field with the project slug
|
||||||
|
_`projectSlug`_, environment slug _`envSlug`_, and secrets path
|
||||||
|
_`secretsPath`_ that you want to fetch secrets from. Please see the example
|
||||||
|
below.
|
||||||
|
</Info>
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: secrets.infisical.com/v1alpha1
|
||||||
|
kind: InfisicalSecret
|
||||||
|
metadata:
|
||||||
|
name: infisicalsecret-sample-crd
|
||||||
|
spec:
|
||||||
|
authentication:
|
||||||
|
ldapAuth:
|
||||||
|
secretsScope:
|
||||||
|
projectSlug: <project-slug> # <-- project slug
|
||||||
|
envSlug: <env-slug> # "dev", "staging", "prod", etc..
|
||||||
|
secretsPath: "<secrets-path>" # Root is "/"
|
||||||
|
identityId: <machine-identity-id>
|
||||||
|
credentialsRef:
|
||||||
|
secretName: ldap-auth-credentials # <-- name of the Kubernetes secret that stores our machine identity credentials
|
||||||
|
secretNamespace: default # <-- namespace of the Kubernetes secret that stores our machine identity credentials
|
||||||
|
```
|
||||||
|
|
||||||
|
</Accordion>
|
||||||
|
|
||||||
<Accordion title="authentication.serviceToken">
|
<Accordion title="authentication.serviceToken">
|
||||||
|
|
||||||
The service token required to authenticate with Infisical needs to be stored in a Kubernetes secret. This block defines the reference to the name and namespace of secret that stores this service token.
|
The service token required to authenticate with Infisical needs to be stored in a Kubernetes secret. This block defines the reference to the name and namespace of secret that stores this service token.
|
||||||
@@ -928,7 +938,9 @@ The properties includes defining the name and namespace of the Kubernetes config
|
|||||||
The Infisical operator will automatically create the Kubernetes config map in the specified name/namespace and ensure it stays up-to-date. If a config map already exists in the specified namespace, the operator will update the existing config map with the new data.
|
The Infisical operator will automatically create the Kubernetes config map in the specified name/namespace and ensure it stays up-to-date. If a config map already exists in the specified namespace, the operator will update the existing config map with the new data.
|
||||||
|
|
||||||
<Warning>
|
<Warning>
|
||||||
The usage of config maps is only intended for storing non-sensitive data. If you are looking to store sensitive data, please use the [managed secret](#operator-managed-secrets) property instead.
|
The usage of config maps is only intended for storing non-sensitive data. If
|
||||||
|
you are looking to store sensitive data, please use the [managed
|
||||||
|
secret](#operator-managed-secrets) property instead.
|
||||||
</Warning>
|
</Warning>
|
||||||
|
|
||||||
<Accordion title="managedKubeConfigMapReferences">
|
<Accordion title="managedKubeConfigMapReferences">
|
||||||
@@ -955,7 +967,6 @@ The Infisical operator will automatically create the Kubernetes config map in th
|
|||||||
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
|
|
||||||
#### Managed ConfigMap Templating
|
#### Managed ConfigMap Templating
|
||||||
|
|
||||||
Fetching secrets from Infisical as is via the operator may not be enough. This is where templating functionality may be helpful.
|
Fetching secrets from Infisical as is via the operator may not be enough. This is where templating functionality may be helpful.
|
||||||
@@ -1025,6 +1036,7 @@ Using Go templates, you can format, combine, and create new key-value pairs from
|
|||||||
### Available templating functions
|
### Available templating functions
|
||||||
|
|
||||||
Please refer to the [templating functions documentation](/integrations/platforms/kubernetes/overview#available-helper-functions) for more information.
|
Please refer to the [templating functions documentation](/integrations/platforms/kubernetes/overview#available-helper-functions) for more information.
|
||||||
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
## Applying CRD
|
## Applying CRD
|
||||||
@@ -1061,8 +1073,6 @@ To verify that the operator has successfully created the managed secret, you can
|
|||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Using Managed Secret In Your Deployment
|
## Using Managed Secret In Your Deployment
|
||||||
|
|
||||||
To make use of the managed secret created by the operator into your deployment can be achieved through several methods.
|
To make use of the managed secret created by the operator into your deployment can be achieved through several methods.
|
||||||
@@ -1150,6 +1160,7 @@ Here, we will highlight three of the most common ways to utilize it. Learn more
|
|||||||
ports:
|
ports:
|
||||||
- containerPort: 80
|
- containerPort: 80
|
||||||
```
|
```
|
||||||
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Accordion title="volumes">
|
<Accordion title="volumes">
|
||||||
@@ -1339,9 +1350,11 @@ secrets.infisical.com/auto-reload: "true"
|
|||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
<Info>
|
<Info>
|
||||||
#### How it works
|
#### How it works When a managed secret is updated, the operator checks for
|
||||||
When a managed secret is updated, the operator checks for any Deployments, DaemonSets, or StatefulSets that consume the updated secret and have the annotation
|
any Deployments, DaemonSets, or StatefulSets that consume the updated secret
|
||||||
`secrets.infisical.com/auto-reload: "true"`. For each matching workload, the operator triggers a rolling restart to ensure it picks up the latest secret values.
|
and have the annotation `secrets.infisical.com/auto-reload: "true"`. For each
|
||||||
|
matching workload, the operator triggers a rolling restart to ensure it picks
|
||||||
|
up the latest secret values.
|
||||||
</Info>
|
</Info>
|
||||||
|
|
||||||
## Using Managed ConfigMap In Your Deployment
|
## Using Managed ConfigMap In Your Deployment
|
||||||
@@ -1350,10 +1363,10 @@ To make use of the managed ConfigMap created by the operator into your deploymen
|
|||||||
Here, we will highlight three of the most common ways to utilize it. Learn more about Kubernetes ConfigMaps [here](https://kubernetes.io/docs/concepts/configuration/configmap/)
|
Here, we will highlight three of the most common ways to utilize it. Learn more about Kubernetes ConfigMaps [here](https://kubernetes.io/docs/concepts/configuration/configmap/)
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
Automatic redeployment of deployments using managed ConfigMaps is not yet supported.
|
Automatic redeployment of deployments using managed ConfigMaps is not yet
|
||||||
|
supported.
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
|
|
||||||
<Accordion title="envFrom">
|
<Accordion title="envFrom">
|
||||||
This will take all the secrets from your managed ConfigMap and expose them to your container
|
This will take all the secrets from your managed ConfigMap and expose them to your container
|
||||||
|
|
||||||
@@ -1490,6 +1503,7 @@ Here, we will highlight three of the most common ways to utilize it. Learn more
|
|||||||
configMap:
|
configMap:
|
||||||
name: managed-configmap # <- managed configmap
|
name: managed-configmap # <- managed configmap
|
||||||
```
|
```
|
||||||
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
The definition file of the Kubernetes secret for the CA certificate can be structured like the following:
|
The definition file of the Kubernetes secret for the CA certificate can be structured like the following:
|
||||||
@@ -1548,4 +1562,5 @@ Thus, if a specific label is required on the resulting secret, it can be applied
|
|||||||
namespace: default
|
namespace: default
|
||||||
type: Opaque
|
type: Opaque
|
||||||
```
|
```
|
||||||
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
@@ -65,14 +65,7 @@ Example values:
|
|||||||
default="false"
|
default="false"
|
||||||
optional
|
optional
|
||||||
>
|
>
|
||||||
Determines whether your Infisical instance can automatically read the service
|
Determines whether your Infisical instance can automatically read the service account token of the pod it's running on. Used for features such as the IRSA auth method.
|
||||||
account token of the pod it's running on. Used for features such as the IRSA
|
|
||||||
auth method.
|
|
||||||
</ParamField>
|
|
||||||
|
|
||||||
<ParamField query="DISABLE_AUDIT_LOG_STORAGE" type="string" default="false">
|
|
||||||
Disable storing audit logs in the database. This is useful if you're using
|
|
||||||
audit log streams and don't want to store them in the database.
|
|
||||||
</ParamField>
|
</ParamField>
|
||||||
|
|
||||||
## CORS
|
## CORS
|
||||||
|
@@ -35,7 +35,6 @@ export type TServerConfig = {
|
|||||||
initialized: boolean;
|
initialized: boolean;
|
||||||
allowSignUp: boolean;
|
allowSignUp: boolean;
|
||||||
allowedSignUpDomain?: string | null;
|
allowedSignUpDomain?: string | null;
|
||||||
disableAuditLogStorage: boolean;
|
|
||||||
isMigrationModeOn?: boolean;
|
isMigrationModeOn?: boolean;
|
||||||
trustSamlEmails: boolean;
|
trustSamlEmails: boolean;
|
||||||
trustLdapEmails: boolean;
|
trustLdapEmails: boolean;
|
||||||
|
@@ -11,7 +11,6 @@ export type TGitHubConnection = TRootAppConnection & { app: AppConnection.GitHub
|
|||||||
method: GitHubConnectionMethod.OAuth;
|
method: GitHubConnectionMethod.OAuth;
|
||||||
credentials: {
|
credentials: {
|
||||||
code: string;
|
code: string;
|
||||||
instanceType?: "cloud" | "server";
|
|
||||||
host?: string;
|
host?: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -20,7 +19,6 @@ export type TGitHubConnection = TRootAppConnection & { app: AppConnection.GitHub
|
|||||||
credentials: {
|
credentials: {
|
||||||
code: string;
|
code: string;
|
||||||
installationId: string;
|
installationId: string;
|
||||||
instanceType?: "cloud" | "server";
|
|
||||||
host?: string;
|
host?: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -12,15 +12,14 @@ export const useCreateReminder = (secretId: string) => {
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
return useMutation<Reminder, object, CreateReminderDTO>({
|
return useMutation<Reminder, object, CreateReminderDTO>({
|
||||||
mutationFn: async ({ message, repeatDays, nextReminderDate, recipients, fromDate }) => {
|
mutationFn: async ({ message, repeatDays, nextReminderDate, recipients }) => {
|
||||||
const { data } = await apiRequest.post<{ reminder: Reminder }>(
|
const { data } = await apiRequest.post<{ reminder: Reminder }>(
|
||||||
`/api/v1/reminders/secrets/${secretId}`,
|
`/api/v1/reminders/secrets/${secretId}`,
|
||||||
{
|
{
|
||||||
message,
|
message,
|
||||||
repeatDays,
|
repeatDays,
|
||||||
nextReminderDate,
|
nextReminderDate,
|
||||||
recipients,
|
recipients
|
||||||
fromDate
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return data.reminder;
|
return data.reminder;
|
||||||
|
@@ -2,7 +2,6 @@ export type CreateReminderDTO = {
|
|||||||
message?: string | null;
|
message?: string | null;
|
||||||
repeatDays?: number | null;
|
repeatDays?: number | null;
|
||||||
nextReminderDate?: Date | null;
|
nextReminderDate?: Date | null;
|
||||||
fromDate?: Date | null;
|
|
||||||
secretId: string;
|
secretId: string;
|
||||||
recipients?: string[];
|
recipients?: string[];
|
||||||
};
|
};
|
||||||
|
@@ -5,5 +5,4 @@ export type ServerStatus = {
|
|||||||
secretScanningConfigured: boolean;
|
secretScanningConfigured: boolean;
|
||||||
redisConfigured: boolean;
|
redisConfigured: boolean;
|
||||||
samlDefaultOrgSlug: string;
|
samlDefaultOrgSlug: string;
|
||||||
auditLogStorageDisabled: boolean;
|
|
||||||
};
|
};
|
||||||
|
@@ -6,11 +6,10 @@ import { twMerge } from "tailwind-merge";
|
|||||||
|
|
||||||
import { CreateOrgModal } from "@app/components/organization/CreateOrgModal";
|
import { CreateOrgModal } from "@app/components/organization/CreateOrgModal";
|
||||||
import { Banner } from "@app/components/page-frames/Banner";
|
import { Banner } from "@app/components/page-frames/Banner";
|
||||||
import { useServerConfig, useSubscription } from "@app/context";
|
import { useServerConfig } from "@app/context";
|
||||||
import { usePopUp } from "@app/hooks";
|
import { usePopUp } from "@app/hooks";
|
||||||
import { useFetchServerStatus } from "@app/hooks/api";
|
import { useFetchServerStatus } from "@app/hooks/api";
|
||||||
|
|
||||||
import { AuditLogBanner } from "./components/AuditLogBanner";
|
|
||||||
import { InsecureConnectionBanner } from "./components/InsecureConnectionBanner";
|
import { InsecureConnectionBanner } from "./components/InsecureConnectionBanner";
|
||||||
import { Navbar } from "./components/NavBar";
|
import { Navbar } from "./components/NavBar";
|
||||||
import { OrgSidebar } from "./components/OrgSidebar";
|
import { OrgSidebar } from "./components/OrgSidebar";
|
||||||
@@ -32,7 +31,6 @@ export const OrganizationLayout = () => {
|
|||||||
const containerHeight = config.pageFrameContent ? "h-[94vh]" : "h-screen";
|
const containerHeight = config.pageFrameContent ? "h-[94vh]" : "h-screen";
|
||||||
|
|
||||||
const { data: serverDetails, isLoading } = useFetchServerStatus();
|
const { data: serverDetails, isLoading } = useFetchServerStatus();
|
||||||
const { subscription } = useSubscription();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -43,7 +41,6 @@ export const OrganizationLayout = () => {
|
|||||||
<Navbar />
|
<Navbar />
|
||||||
{!isLoading && !serverDetails?.redisConfigured && <RedisBanner />}
|
{!isLoading && !serverDetails?.redisConfigured && <RedisBanner />}
|
||||||
{!isLoading && !serverDetails?.emailConfigured && <SmtpBanner />}
|
{!isLoading && !serverDetails?.emailConfigured && <SmtpBanner />}
|
||||||
{!isLoading && subscription.auditLogs && <AuditLogBanner />}
|
|
||||||
{!window.isSecureContext && <InsecureConnectionBanner />}
|
{!window.isSecureContext && <InsecureConnectionBanner />}
|
||||||
<div className="flex flex-grow flex-col overflow-y-hidden md:flex-row">
|
<div className="flex flex-grow flex-col overflow-y-hidden md:flex-row">
|
||||||
<OrgSidebar isHidden={isInsideProject} />
|
<OrgSidebar isHidden={isInsideProject} />
|
||||||
|
@@ -1,23 +0,0 @@
|
|||||||
import { useOrganization } from "@app/context";
|
|
||||||
import { useFetchServerStatus, useGetAuditLogStreams } from "@app/hooks/api";
|
|
||||||
|
|
||||||
import { OrgAlertBanner } from "../OrgAlertBanner";
|
|
||||||
|
|
||||||
export const AuditLogBanner = () => {
|
|
||||||
const org = useOrganization();
|
|
||||||
const { data: status, isLoading: isLoadingStatus } = useFetchServerStatus();
|
|
||||||
const { data: streams, isLoading: isLoadingStreams } = useGetAuditLogStreams(org.currentOrg.id);
|
|
||||||
|
|
||||||
if (isLoadingStreams || isLoadingStatus || !streams) return null;
|
|
||||||
|
|
||||||
if (status?.auditLogStorageDisabled && !streams.length) {
|
|
||||||
return (
|
|
||||||
<OrgAlertBanner
|
|
||||||
text="Attention: Audit logs storage is disabled but no audit log streams have been configured."
|
|
||||||
link="https://infisical.com/docs/documentation/platform/audit-log-streams/audit-log-streams"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
@@ -1 +0,0 @@
|
|||||||
export * from "./AuditLogBanner";
|
|
@@ -48,16 +48,9 @@ const formSchema = genericAppConnectionFieldsSchema.extend({
|
|||||||
app: z.literal(AppConnection.GitHub),
|
app: z.literal(AppConnection.GitHub),
|
||||||
method: z.nativeEnum(GitHubConnectionMethod),
|
method: z.nativeEnum(GitHubConnectionMethod),
|
||||||
credentials: z
|
credentials: z
|
||||||
.union([
|
.object({
|
||||||
z.object({
|
|
||||||
instanceType: z.literal("cloud").optional(),
|
|
||||||
host: z.string().optional()
|
host: z.string().optional()
|
||||||
}),
|
|
||||||
z.object({
|
|
||||||
instanceType: z.literal("server"),
|
|
||||||
host: z.string().min(1, "Required")
|
|
||||||
})
|
})
|
||||||
])
|
|
||||||
.optional()
|
.optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -77,10 +70,7 @@ export const GitHubConnectionForm = ({ appConnection }: Props) => {
|
|||||||
defaultValues: appConnection ?? {
|
defaultValues: appConnection ?? {
|
||||||
app: AppConnection.GitHub,
|
app: AppConnection.GitHub,
|
||||||
method: GitHubConnectionMethod.App,
|
method: GitHubConnectionMethod.App,
|
||||||
gatewayId: null,
|
gatewayId: null
|
||||||
credentials: {
|
|
||||||
instanceType: "cloud"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -88,7 +78,6 @@ export const GitHubConnectionForm = ({ appConnection }: Props) => {
|
|||||||
handleSubmit,
|
handleSubmit,
|
||||||
control,
|
control,
|
||||||
watch,
|
watch,
|
||||||
setValue,
|
|
||||||
formState: { isSubmitting, isDirty }
|
formState: { isSubmitting, isDirty }
|
||||||
} = form;
|
} = form;
|
||||||
|
|
||||||
@@ -96,7 +85,6 @@ export const GitHubConnectionForm = ({ appConnection }: Props) => {
|
|||||||
const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list());
|
const { data: gateways, isPending: isGatewaysLoading } = useQuery(gatewaysQueryKeys.list());
|
||||||
|
|
||||||
const selectedMethod = watch("method");
|
const selectedMethod = watch("method");
|
||||||
const instanceType = watch("credentials.instanceType");
|
|
||||||
|
|
||||||
const onSubmit = (formData: FormData) => {
|
const onSubmit = (formData: FormData) => {
|
||||||
setIsRedirecting(true);
|
setIsRedirecting(true);
|
||||||
@@ -115,7 +103,7 @@ export const GitHubConnectionForm = ({ appConnection }: Props) => {
|
|||||||
switch (formData.method) {
|
switch (formData.method) {
|
||||||
case GitHubConnectionMethod.App:
|
case GitHubConnectionMethod.App:
|
||||||
window.location.assign(
|
window.location.assign(
|
||||||
`${githubHost}/${formData.credentials?.instanceType === "server" ? "github-apps" : "apps"}/${appClientSlug}/installations/new?state=${state}`
|
`${githubHost}/apps/${appClientSlug}/installations/new?state=${state}`
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case GitHubConnectionMethod.OAuth:
|
case GitHubConnectionMethod.OAuth:
|
||||||
@@ -187,54 +175,13 @@ export const GitHubConnectionForm = ({ appConnection }: Props) => {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
{subscription.gateway && (
|
||||||
<Accordion type="single" collapsible className="w-full">
|
<Accordion type="single" collapsible className="w-full">
|
||||||
<AccordionItem value="enterprise-options" className="data-[state=open]:border-none">
|
<AccordionItem value="enterprise-options" className="data-[state=open]:border-none">
|
||||||
<AccordionTrigger className="h-fit flex-none pl-1 text-sm">
|
<AccordionTrigger className="h-fit flex-none pl-1 text-sm">
|
||||||
<div className="order-1 ml-3">GitHub Enterprise Options</div>
|
<div className="order-1 ml-3">GitHub Enterprise Options</div>
|
||||||
</AccordionTrigger>
|
</AccordionTrigger>
|
||||||
<AccordionContent childrenClassName="px-0">
|
<AccordionContent childrenClassName="px-0">
|
||||||
<Controller
|
|
||||||
name="credentials.instanceType"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControl label="Instance Type">
|
|
||||||
<Select
|
|
||||||
value={field.value}
|
|
||||||
onValueChange={(e) => {
|
|
||||||
field.onChange(e);
|
|
||||||
if (e === "cloud") {
|
|
||||||
setValue("gatewayId", null);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className="w-full border border-mineshaft-500"
|
|
||||||
dropdownContainerClassName="max-w-none"
|
|
||||||
placeholder="Enterprise Cloud"
|
|
||||||
position="popper"
|
|
||||||
>
|
|
||||||
<SelectItem value="cloud">Enterprise Cloud</SelectItem>
|
|
||||||
<SelectItem value="server">Enterprise Server</SelectItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Controller
|
|
||||||
name="credentials.host"
|
|
||||||
control={control}
|
|
||||||
shouldUnregister
|
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
errorText={error?.message}
|
|
||||||
isError={Boolean(error?.message)}
|
|
||||||
label="Instance Hostname"
|
|
||||||
isOptional={instanceType === "cloud"}
|
|
||||||
isRequired={instanceType === "server"}
|
|
||||||
>
|
|
||||||
<Input {...field} placeholder="github.com" />
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{subscription.gateway && instanceType === "server" && (
|
|
||||||
<OrgPermissionCan
|
<OrgPermissionCan
|
||||||
I={OrgGatewayPermissionActions.AttachGateways}
|
I={OrgGatewayPermissionActions.AttachGateways}
|
||||||
a={OrgPermissionSubjects.Gateway}
|
a={OrgPermissionSubjects.Gateway}
|
||||||
@@ -243,6 +190,7 @@ export const GitHubConnectionForm = ({ appConnection }: Props) => {
|
|||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="gatewayId"
|
name="gatewayId"
|
||||||
|
defaultValue=""
|
||||||
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
render={({ field: { value, onChange }, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
isError={Boolean(error?.message)}
|
isError={Boolean(error?.message)}
|
||||||
@@ -256,7 +204,7 @@ export const GitHubConnectionForm = ({ appConnection }: Props) => {
|
|||||||
<div>
|
<div>
|
||||||
<Select
|
<Select
|
||||||
isDisabled={!isAllowed}
|
isDisabled={!isAllowed}
|
||||||
value={value || (null as unknown as string)}
|
value={value as string}
|
||||||
onValueChange={onChange}
|
onValueChange={onChange}
|
||||||
className="w-full border border-mineshaft-500"
|
className="w-full border border-mineshaft-500"
|
||||||
dropdownContainerClassName="max-w-none"
|
dropdownContainerClassName="max-w-none"
|
||||||
@@ -266,7 +214,7 @@ export const GitHubConnectionForm = ({ appConnection }: Props) => {
|
|||||||
>
|
>
|
||||||
<SelectItem
|
<SelectItem
|
||||||
value={null as unknown as string}
|
value={null as unknown as string}
|
||||||
onClick={() => onChange(null)}
|
onClick={() => onChange(undefined)}
|
||||||
>
|
>
|
||||||
Internet Gateway
|
Internet Gateway
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
@@ -283,10 +231,25 @@ export const GitHubConnectionForm = ({ appConnection }: Props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</OrgPermissionCan>
|
||||||
|
<Controller
|
||||||
|
name="credentials.host"
|
||||||
|
control={control}
|
||||||
|
shouldUnregister
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
errorText={error?.message}
|
||||||
|
isError={Boolean(error?.message)}
|
||||||
|
label="Hostname"
|
||||||
|
isOptional
|
||||||
|
>
|
||||||
|
<Input {...field} placeholder="github.com" />
|
||||||
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
|
/>
|
||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
)}
|
||||||
<div className="mt-8 flex items-center">
|
<div className="mt-8 flex items-center">
|
||||||
<Button
|
<Button
|
||||||
className="mr-4"
|
className="mr-4"
|
||||||
|
@@ -408,7 +408,6 @@ export const OAuthCallbackPage = () => {
|
|||||||
credentials: {
|
credentials: {
|
||||||
code: code as string,
|
code: code as string,
|
||||||
installationId: installationId as string,
|
installationId: installationId as string,
|
||||||
...(credentials?.instanceType && { instanceType: credentials.instanceType }),
|
|
||||||
...(credentials?.host && { host: credentials.host })
|
...(credentials?.host && { host: credentials.host })
|
||||||
},
|
},
|
||||||
gatewayId
|
gatewayId
|
||||||
@@ -417,7 +416,6 @@ export const OAuthCallbackPage = () => {
|
|||||||
connectionId,
|
connectionId,
|
||||||
credentials: {
|
credentials: {
|
||||||
code: code as string,
|
code: code as string,
|
||||||
...(credentials?.instanceType && { instanceType: credentials.instanceType }),
|
|
||||||
...(credentials?.host && { host: credentials.host })
|
...(credentials?.host && { host: credentials.host })
|
||||||
},
|
},
|
||||||
gatewayId
|
gatewayId
|
||||||
@@ -433,7 +431,6 @@ export const OAuthCallbackPage = () => {
|
|||||||
method: GitHubConnectionMethod.App,
|
method: GitHubConnectionMethod.App,
|
||||||
credentials: {
|
credentials: {
|
||||||
code: code as string,
|
code: code as string,
|
||||||
...(credentials?.instanceType && { instanceType: credentials.instanceType }),
|
|
||||||
installationId: installationId as string,
|
installationId: installationId as string,
|
||||||
...(credentials?.host && { host: credentials.host })
|
...(credentials?.host && { host: credentials.host })
|
||||||
},
|
},
|
||||||
@@ -443,7 +440,6 @@ export const OAuthCallbackPage = () => {
|
|||||||
method: GitHubConnectionMethod.OAuth,
|
method: GitHubConnectionMethod.OAuth,
|
||||||
credentials: {
|
credentials: {
|
||||||
code: code as string,
|
code: code as string,
|
||||||
...(credentials?.instanceType && { instanceType: credentials.instanceType }),
|
|
||||||
...(credentials?.host && { host: credentials.host })
|
...(credentials?.host && { host: credentials.host })
|
||||||
},
|
},
|
||||||
gatewayId
|
gatewayId
|
||||||
|
@@ -12,7 +12,6 @@ export const AuditLogsPage = () => {
|
|||||||
<link rel="icon" href="/infisical.ico" />
|
<link rel="icon" href="/infisical.ico" />
|
||||||
<meta property="og:image" content="/images/message.png" />
|
<meta property="og:image" content="/images/message.png" />
|
||||||
</Helmet>
|
</Helmet>
|
||||||
|
|
||||||
<div className="flex h-full w-full justify-center bg-bunker-800 text-white">
|
<div className="flex h-full w-full justify-center bg-bunker-800 text-white">
|
||||||
<div className="w-full max-w-7xl">
|
<div className="w-full max-w-7xl">
|
||||||
<PageHeader
|
<PageHeader
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Fragment } from "react";
|
import { Fragment } from "react";
|
||||||
import { faCancel, faFile } from "@fortawesome/free-solid-svg-icons";
|
import { faFile } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
Tr
|
Tr
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { Timezone } from "@app/helpers/datetime";
|
import { Timezone } from "@app/helpers/datetime";
|
||||||
import { useFetchServerStatus, useGetAuditLogs } from "@app/hooks/api";
|
import { useGetAuditLogs } from "@app/hooks/api";
|
||||||
import { TGetAuditLogsFilter } from "@app/hooks/api/auditLogs/types";
|
import { TGetAuditLogsFilter } from "@app/hooks/api/auditLogs/types";
|
||||||
|
|
||||||
import { LogsTableRow } from "./LogsTableRow";
|
import { LogsTableRow } from "./LogsTableRow";
|
||||||
@@ -30,8 +30,6 @@ type Props = {
|
|||||||
const AUDIT_LOG_LIMIT = 30;
|
const AUDIT_LOG_LIMIT = 30;
|
||||||
|
|
||||||
export const LogsTable = ({ filter, refetchInterval, timezone }: Props) => {
|
export const LogsTable = ({ filter, refetchInterval, timezone }: Props) => {
|
||||||
const { data: status } = useFetchServerStatus();
|
|
||||||
|
|
||||||
// Determine the project ID for filtering
|
// Determine the project ID for filtering
|
||||||
const filterProjectId =
|
const filterProjectId =
|
||||||
// Use the projectId from the filter if it exists
|
// Use the projectId from the filter if it exists
|
||||||
@@ -81,11 +79,7 @@ export const LogsTable = ({ filter, refetchInterval, timezone }: Props) => {
|
|||||||
{isEmpty && (
|
{isEmpty && (
|
||||||
<Tr>
|
<Tr>
|
||||||
<Td colSpan={3}>
|
<Td colSpan={3}>
|
||||||
{status?.auditLogStorageDisabled ? (
|
|
||||||
<EmptyState title="Audit log storage is disabled" icon={faCancel} />
|
|
||||||
) : (
|
|
||||||
<EmptyState title="No audit logs on file" icon={faFile} />
|
<EmptyState title="No audit logs on file" icon={faFile} />
|
||||||
)}
|
|
||||||
</Td>
|
</Td>
|
||||||
</Tr>
|
</Tr>
|
||||||
)}
|
)}
|
||||||
|
@@ -52,15 +52,8 @@ export const SecretSearchInput = ({
|
|||||||
if (activeIndex === 0 && e.key === "Enter") setIsOpen(true);
|
if (activeIndex === 0 && e.key === "Enter") setIsOpen(true);
|
||||||
}}
|
}}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
className={twMerge(
|
className="input text-md h-[2.3rem] w-full rounded-md rounded-l-none bg-mineshaft-800 py-[0.375rem] pl-2.5 pr-8 text-gray-400 placeholder-mineshaft-50 placeholder-opacity-50 outline-none duration-200 placeholder:text-sm hover:ring-bunker-400/60 focus:bg-mineshaft-700/80 focus:ring-1 focus:ring-primary-400/50"
|
||||||
"input text-md h-[2.3rem] w-full rounded-md rounded-l-none bg-mineshaft-800 py-[0.375rem] pl-2.5 text-gray-400 placeholder-mineshaft-50 placeholder-opacity-50 outline-none duration-200 placeholder:text-sm hover:ring-bunker-400/60 focus:bg-mineshaft-700/80 focus:ring-1 focus:ring-primary-400/50",
|
placeholder="Search by secret, folder, tag or metadata..."
|
||||||
hasSearch ? "pr-8" : "pr-2.5"
|
|
||||||
)}
|
|
||||||
placeholder={
|
|
||||||
isSingleEnv
|
|
||||||
? "Search by secret, folder, tag or metadata..."
|
|
||||||
: "Search by secret or folder name..."
|
|
||||||
}
|
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(e) => onChange(e.target.value)}
|
onChange={(e) => onChange(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
@@ -537,21 +537,17 @@ export const SecretApprovalRequestChanges = ({
|
|||||||
<div
|
<div
|
||||||
className="flex flex-nowrap items-center justify-between space-x-2 rounded border border-mineshaft-600 bg-mineshaft-800 px-2 py-1"
|
className="flex flex-nowrap items-center justify-between space-x-2 rounded border border-mineshaft-600 bg-mineshaft-800 px-2 py-1"
|
||||||
key={`required-approver-${requiredApprover.userId}`}
|
key={`required-approver-${requiredApprover.userId}`}
|
||||||
>
|
|
||||||
<Tooltip
|
|
||||||
content={
|
|
||||||
requiredApprover.firstName
|
|
||||||
? `${requiredApprover.firstName || ""} ${requiredApprover.lastName || ""}`
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
position="left"
|
|
||||||
sideOffset={10}
|
|
||||||
>
|
>
|
||||||
<div className="flex text-sm">
|
<div className="flex text-sm">
|
||||||
<div>{requiredApprover?.email}</div>
|
<Tooltip
|
||||||
|
content={`${requiredApprover.firstName || ""} ${
|
||||||
|
requiredApprover.lastName || ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<span>{requiredApprover?.email}</span>
|
||||||
|
</Tooltip>
|
||||||
<span className="text-red">*</span>
|
<span className="text-red">*</span>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
|
||||||
<div>
|
<div>
|
||||||
{reviewer?.comment && (
|
{reviewer?.comment && (
|
||||||
<Tooltip className="max-w-lg break-words" content={reviewer.comment}>
|
<Tooltip className="max-w-lg break-words" content={reviewer.comment}>
|
||||||
|
@@ -4,7 +4,6 @@ import { faClock, faTrash } from "@fortawesome/free-solid-svg-icons";
|
|||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
import { format } from "date-fns";
|
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@@ -34,7 +33,6 @@ const MIN_REPEAT_DAYS = 1;
|
|||||||
const MAX_REPEAT_DAYS = 365;
|
const MAX_REPEAT_DAYS = 365;
|
||||||
const DEFAULT_REPEAT_DAYS = 30;
|
const DEFAULT_REPEAT_DAYS = 30;
|
||||||
const DEFAULT_TEXTAREA_ROWS = 8;
|
const DEFAULT_TEXTAREA_ROWS = 8;
|
||||||
const ONE_DAY_IN_MILLIS = 86400000;
|
|
||||||
|
|
||||||
// Enums
|
// Enums
|
||||||
enum ReminderType {
|
enum ReminderType {
|
||||||
@@ -81,11 +79,6 @@ const ReminderFormSchema = z.object({
|
|||||||
.refine((data) => data > new Date(), { message: "Reminder date must be in the future" })
|
.refine((data) => data > new Date(), { message: "Reminder date must be in the future" })
|
||||||
.nullable()
|
.nullable()
|
||||||
.optional(),
|
.optional(),
|
||||||
fromDate: z.coerce
|
|
||||||
.date()
|
|
||||||
.refine((data) => data > new Date(), { message: "From date must be in the future" })
|
|
||||||
.nullable()
|
|
||||||
.optional(),
|
|
||||||
reminderType: z.enum(["Recurring", "One Time"])
|
reminderType: z.enum(["Recurring", "One Time"])
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -93,7 +86,7 @@ export type TReminderFormSchema = z.infer<typeof ReminderFormSchema>;
|
|||||||
|
|
||||||
// Custom hook for form state management
|
// Custom hook for form state management
|
||||||
const useReminderForm = (reminderData?: Reminder) => {
|
const useReminderForm = (reminderData?: Reminder) => {
|
||||||
const { repeatDays, message, nextReminderDate, fromDate } = reminderData || {};
|
const { repeatDays, message, nextReminderDate } = reminderData || {};
|
||||||
|
|
||||||
const isEditMode = Boolean(reminderData);
|
const isEditMode = Boolean(reminderData);
|
||||||
|
|
||||||
@@ -103,10 +96,9 @@ const useReminderForm = (reminderData?: Reminder) => {
|
|||||||
message: message || "",
|
message: message || "",
|
||||||
nextReminderDate: nextReminderDate || null,
|
nextReminderDate: nextReminderDate || null,
|
||||||
reminderType: repeatDays ? ReminderType.Recurring : ReminderType.OneTime,
|
reminderType: repeatDays ? ReminderType.Recurring : ReminderType.OneTime,
|
||||||
recipients: [],
|
recipients: []
|
||||||
fromDate
|
|
||||||
}),
|
}),
|
||||||
[repeatDays, message, nextReminderDate, fromDate]
|
[repeatDays, message, nextReminderDate]
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -161,8 +153,7 @@ export const CreateReminderForm = ({
|
|||||||
message: reminderData?.message || "",
|
message: reminderData?.message || "",
|
||||||
nextReminderDate: reminderData?.nextReminderDate || null,
|
nextReminderDate: reminderData?.nextReminderDate || null,
|
||||||
reminderType: reminderData?.repeatDays ? ReminderType.Recurring : ReminderType.OneTime,
|
reminderType: reminderData?.repeatDays ? ReminderType.Recurring : ReminderType.OneTime,
|
||||||
recipients: [],
|
recipients: []
|
||||||
fromDate: reminderData?.fromDate
|
|
||||||
},
|
},
|
||||||
resolver: zodResolver(ReminderFormSchema)
|
resolver: zodResolver(ReminderFormSchema)
|
||||||
});
|
});
|
||||||
@@ -179,7 +170,6 @@ export const CreateReminderForm = ({
|
|||||||
|
|
||||||
// Watch form values
|
// Watch form values
|
||||||
const reminderType = watch("reminderType");
|
const reminderType = watch("reminderType");
|
||||||
const fromDate = watch("fromDate");
|
|
||||||
|
|
||||||
// Invalidate queries helper
|
// Invalidate queries helper
|
||||||
const invalidateQueries = () => {
|
const invalidateQueries = () => {
|
||||||
@@ -205,8 +195,7 @@ export const CreateReminderForm = ({
|
|||||||
message: data.message,
|
message: data.message,
|
||||||
recipients: data.recipients?.map((r) => r.value) || [],
|
recipients: data.recipients?.map((r) => r.value) || [],
|
||||||
secretId,
|
secretId,
|
||||||
nextReminderDate: data.nextReminderDate,
|
nextReminderDate: data.nextReminderDate
|
||||||
fromDate: data.fromDate
|
|
||||||
});
|
});
|
||||||
|
|
||||||
invalidateQueries();
|
invalidateQueries();
|
||||||
@@ -254,7 +243,6 @@ export const CreateReminderForm = ({
|
|||||||
if (newType === ReminderType.Recurring) {
|
if (newType === ReminderType.Recurring) {
|
||||||
setValue("repeatDays", DEFAULT_REPEAT_DAYS);
|
setValue("repeatDays", DEFAULT_REPEAT_DAYS);
|
||||||
setValue("nextReminderDate", null);
|
setValue("nextReminderDate", null);
|
||||||
setValue("fromDate", null);
|
|
||||||
} else if (newType === ReminderType.OneTime) {
|
} else if (newType === ReminderType.OneTime) {
|
||||||
const tomorrow = new Date();
|
const tomorrow = new Date();
|
||||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||||
@@ -271,7 +259,6 @@ export const CreateReminderForm = ({
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
repeatDays: repeatDaysInitial,
|
repeatDays: repeatDaysInitial,
|
||||||
fromDate: fromDateInitial,
|
|
||||||
message,
|
message,
|
||||||
recipients,
|
recipients,
|
||||||
nextReminderDate: nextReminderDateInitial
|
nextReminderDate: nextReminderDateInitial
|
||||||
@@ -279,7 +266,6 @@ export const CreateReminderForm = ({
|
|||||||
|
|
||||||
if (repeatDaysInitial) {
|
if (repeatDaysInitial) {
|
||||||
setValue("repeatDays", repeatDaysInitial);
|
setValue("repeatDays", repeatDaysInitial);
|
||||||
setValue("fromDate", fromDateInitial);
|
|
||||||
setValue("reminderType", ReminderType.Recurring);
|
setValue("reminderType", ReminderType.Recurring);
|
||||||
} else {
|
} else {
|
||||||
setValue("reminderType", ReminderType.OneTime);
|
setValue("reminderType", ReminderType.OneTime);
|
||||||
@@ -337,7 +323,6 @@ export const CreateReminderForm = ({
|
|||||||
|
|
||||||
{/* Conditional Fields Based on Reminder Type */}
|
{/* Conditional Fields Based on Reminder Type */}
|
||||||
{reminderType === ReminderType.Recurring ? (
|
{reminderType === ReminderType.Recurring ? (
|
||||||
<div className="grid grid-cols-[1fr,auto] gap-x-2">
|
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="repeatDays"
|
name="repeatDays"
|
||||||
@@ -362,6 +347,7 @@ export const CreateReminderForm = ({
|
|||||||
max={MAX_REPEAT_DAYS}
|
max={MAX_REPEAT_DAYS}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
{/* Interval description */}
|
{/* Interval description */}
|
||||||
<div
|
<div
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
@@ -371,39 +357,10 @@ export const CreateReminderForm = ({
|
|||||||
>
|
>
|
||||||
A reminder will be sent every{" "}
|
A reminder will be sent every{" "}
|
||||||
{field.value && field.value > 1 ? `${field.value} days` : "day"}
|
{field.value && field.value > 1 ? `${field.value} days` : "day"}
|
||||||
{fromDate ? ` starting from ${format(fromDate, "MM/dd/yy")}` : ""}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="fromDate"
|
|
||||||
render={({ field, fieldState }) => (
|
|
||||||
<FormControl
|
|
||||||
className="mb-0"
|
|
||||||
label="Start Date"
|
|
||||||
tooltipText="When enabled, this date will be used as the start date for the first reminder"
|
|
||||||
isError={Boolean(fieldState.error)}
|
|
||||||
errorText={fieldState.error?.message || ""}
|
|
||||||
>
|
|
||||||
<DatePicker
|
|
||||||
value={field.value || undefined}
|
|
||||||
className="w-full"
|
|
||||||
onChange={field.onChange}
|
|
||||||
dateFormat="P"
|
|
||||||
popUpProps={{
|
|
||||||
open: isDatePickerOpen,
|
|
||||||
onOpenChange: setIsDatePickerOpen
|
|
||||||
}}
|
|
||||||
popUpContentProps={{}}
|
|
||||||
hideTime
|
|
||||||
hidden={{ before: new Date(Date.now() + ONE_DAY_IN_MILLIS) }}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : (
|
) : (
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
@@ -428,7 +385,7 @@ export const CreateReminderForm = ({
|
|||||||
}}
|
}}
|
||||||
popUpContentProps={{}}
|
popUpContentProps={{}}
|
||||||
hideTime
|
hideTime
|
||||||
hidden={{ before: new Date(Date.now() + ONE_DAY_IN_MILLIS) }}
|
hidden={{ before: new Date(Date.now() + 86400000) }}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -13,6 +13,8 @@ type GenericInfisicalAuthentication struct {
|
|||||||
GcpIdTokenAuth GenericGcpIdTokenAuth `json:"gcpIdTokenAuth,omitempty"`
|
GcpIdTokenAuth GenericGcpIdTokenAuth `json:"gcpIdTokenAuth,omitempty"`
|
||||||
// +kubebuilder:validation:Optional
|
// +kubebuilder:validation:Optional
|
||||||
GcpIamAuth GenericGcpIamAuth `json:"gcpIamAuth,omitempty"`
|
GcpIamAuth GenericGcpIamAuth `json:"gcpIamAuth,omitempty"`
|
||||||
|
// +kubebuilder:validation:Optional
|
||||||
|
LdapAuth GenericLdapAuth `json:"ldapAuth,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GenericUniversalAuth struct {
|
type GenericUniversalAuth struct {
|
||||||
@@ -20,6 +22,13 @@ type GenericUniversalAuth struct {
|
|||||||
CredentialsRef KubeSecretReference `json:"credentialsRef"`
|
CredentialsRef KubeSecretReference `json:"credentialsRef"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GenericLdapAuth struct {
|
||||||
|
// +kubebuilder:validation:Required
|
||||||
|
IdentityID string `json:"identityId"`
|
||||||
|
// +kubebuilder:validation:Required
|
||||||
|
CredentialsRef KubeSecretReference `json:"credentialsRef"`
|
||||||
|
}
|
||||||
|
|
||||||
type GenericAwsIamAuth struct {
|
type GenericAwsIamAuth struct {
|
||||||
// +kubebuilder:validation:Required
|
// +kubebuilder:validation:Required
|
||||||
IdentityID string `json:"identityId"`
|
IdentityID string `json:"identityId"`
|
||||||
|
@@ -21,6 +21,8 @@ type Authentication struct {
|
|||||||
GcpIdTokenAuth GCPIdTokenAuthDetails `json:"gcpIdTokenAuth"`
|
GcpIdTokenAuth GCPIdTokenAuthDetails `json:"gcpIdTokenAuth"`
|
||||||
// +kubebuilder:validation:Optional
|
// +kubebuilder:validation:Optional
|
||||||
GcpIamAuth GcpIamAuthDetails `json:"gcpIamAuth"`
|
GcpIamAuth GcpIamAuthDetails `json:"gcpIamAuth"`
|
||||||
|
// +kubebuilder:validation:Optional
|
||||||
|
LdapAuth LdapAuthDetails `json:"ldapAuth"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UniversalAuthDetails struct {
|
type UniversalAuthDetails struct {
|
||||||
@@ -30,6 +32,15 @@ type UniversalAuthDetails struct {
|
|||||||
SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"`
|
SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LdapAuthDetails struct {
|
||||||
|
// +kubebuilder:validation:Required
|
||||||
|
IdentityID string `json:"identityId"`
|
||||||
|
// +kubebuilder:validation:Required
|
||||||
|
CredentialsRef KubeSecretReference `json:"credentialsRef"`
|
||||||
|
// +kubebuilder:validation:Required
|
||||||
|
SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"`
|
||||||
|
}
|
||||||
|
|
||||||
type KubernetesAuthDetails struct {
|
type KubernetesAuthDetails struct {
|
||||||
// +kubebuilder:validation:Required
|
// +kubebuilder:validation:Required
|
||||||
IdentityID string `json:"identityId"`
|
IdentityID string `json:"identityId"`
|
||||||
|
@@ -53,6 +53,7 @@ func (in *Authentication) DeepCopyInto(out *Authentication) {
|
|||||||
out.AzureAuth = in.AzureAuth
|
out.AzureAuth = in.AzureAuth
|
||||||
out.GcpIdTokenAuth = in.GcpIdTokenAuth
|
out.GcpIdTokenAuth = in.GcpIdTokenAuth
|
||||||
out.GcpIamAuth = in.GcpIamAuth
|
out.GcpIamAuth = in.GcpIamAuth
|
||||||
|
out.LdapAuth = in.LdapAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Authentication.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Authentication.
|
||||||
@@ -326,6 +327,7 @@ func (in *GenericInfisicalAuthentication) DeepCopyInto(out *GenericInfisicalAuth
|
|||||||
out.AzureAuth = in.AzureAuth
|
out.AzureAuth = in.AzureAuth
|
||||||
out.GcpIdTokenAuth = in.GcpIdTokenAuth
|
out.GcpIdTokenAuth = in.GcpIdTokenAuth
|
||||||
out.GcpIamAuth = in.GcpIamAuth
|
out.GcpIamAuth = in.GcpIamAuth
|
||||||
|
out.LdapAuth = in.LdapAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericInfisicalAuthentication.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericInfisicalAuthentication.
|
||||||
@@ -359,6 +361,22 @@ func (in *GenericKubernetesAuth) DeepCopy() *GenericKubernetesAuth {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *GenericLdapAuth) DeepCopyInto(out *GenericLdapAuth) {
|
||||||
|
*out = *in
|
||||||
|
out.CredentialsRef = in.CredentialsRef
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericLdapAuth.
|
||||||
|
func (in *GenericLdapAuth) DeepCopy() *GenericLdapAuth {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(GenericLdapAuth)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *GenericUniversalAuth) DeepCopyInto(out *GenericUniversalAuth) {
|
func (in *GenericUniversalAuth) DeepCopyInto(out *GenericUniversalAuth) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@@ -810,6 +828,23 @@ func (in *KubernetesServiceAccountRef) DeepCopy() *KubernetesServiceAccountRef {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *LdapAuthDetails) DeepCopyInto(out *LdapAuthDetails) {
|
||||||
|
*out = *in
|
||||||
|
out.CredentialsRef = in.CredentialsRef
|
||||||
|
out.SecretsScope = in.SecretsScope
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LdapAuthDetails.
|
||||||
|
func (in *LdapAuthDetails) DeepCopy() *LdapAuthDetails {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(LdapAuthDetails)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *MachineIdentityScopeInWorkspace) DeepCopyInto(out *MachineIdentityScopeInWorkspace) {
|
func (in *MachineIdentityScopeInWorkspace) DeepCopyInto(out *MachineIdentityScopeInWorkspace) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
@@ -103,6 +103,27 @@ spec:
|
|||||||
- identityId
|
- identityId
|
||||||
- serviceAccountRef
|
- serviceAccountRef
|
||||||
type: object
|
type: object
|
||||||
|
ldapAuth:
|
||||||
|
properties:
|
||||||
|
credentialsRef:
|
||||||
|
properties:
|
||||||
|
secretName:
|
||||||
|
description: The name of the Kubernetes Secret
|
||||||
|
type: string
|
||||||
|
secretNamespace:
|
||||||
|
description: The name space where the Kubernetes Secret
|
||||||
|
is located
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- secretName
|
||||||
|
- secretNamespace
|
||||||
|
type: object
|
||||||
|
identityId:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- credentialsRef
|
||||||
|
- identityId
|
||||||
|
type: object
|
||||||
universalAuth:
|
universalAuth:
|
||||||
properties:
|
properties:
|
||||||
credentialsRef:
|
credentialsRef:
|
||||||
|
@@ -103,6 +103,27 @@ spec:
|
|||||||
- identityId
|
- identityId
|
||||||
- serviceAccountRef
|
- serviceAccountRef
|
||||||
type: object
|
type: object
|
||||||
|
ldapAuth:
|
||||||
|
properties:
|
||||||
|
credentialsRef:
|
||||||
|
properties:
|
||||||
|
secretName:
|
||||||
|
description: The name of the Kubernetes Secret
|
||||||
|
type: string
|
||||||
|
secretNamespace:
|
||||||
|
description: The name space where the Kubernetes Secret
|
||||||
|
is located
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- secretName
|
||||||
|
- secretNamespace
|
||||||
|
type: object
|
||||||
|
identityId:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- credentialsRef
|
||||||
|
- identityId
|
||||||
|
type: object
|
||||||
universalAuth:
|
universalAuth:
|
||||||
properties:
|
properties:
|
||||||
credentialsRef:
|
credentialsRef:
|
||||||
|
@@ -181,6 +181,43 @@ spec:
|
|||||||
- secretsScope
|
- secretsScope
|
||||||
- serviceAccountRef
|
- serviceAccountRef
|
||||||
type: object
|
type: object
|
||||||
|
ldapAuth:
|
||||||
|
properties:
|
||||||
|
credentialsRef:
|
||||||
|
properties:
|
||||||
|
secretName:
|
||||||
|
description: The name of the Kubernetes Secret
|
||||||
|
type: string
|
||||||
|
secretNamespace:
|
||||||
|
description: The name space where the Kubernetes Secret
|
||||||
|
is located
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- secretName
|
||||||
|
- secretNamespace
|
||||||
|
type: object
|
||||||
|
identityId:
|
||||||
|
type: string
|
||||||
|
secretsScope:
|
||||||
|
properties:
|
||||||
|
envSlug:
|
||||||
|
type: string
|
||||||
|
projectSlug:
|
||||||
|
type: string
|
||||||
|
recursive:
|
||||||
|
type: boolean
|
||||||
|
secretsPath:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- envSlug
|
||||||
|
- projectSlug
|
||||||
|
- secretsPath
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- credentialsRef
|
||||||
|
- identityId
|
||||||
|
- secretsScope
|
||||||
|
type: object
|
||||||
serviceAccount:
|
serviceAccount:
|
||||||
properties:
|
properties:
|
||||||
environmentName:
|
environmentName:
|
||||||
|
@@ -65,6 +65,19 @@ spec:
|
|||||||
secretsPath: "/path"
|
secretsPath: "/path"
|
||||||
recursive: true
|
recursive: true
|
||||||
|
|
||||||
|
ldapAuth:
|
||||||
|
identityId: <machine-identity-id>
|
||||||
|
credentialsRef:
|
||||||
|
secretName: <secret-name> # ldap-auth-credentials
|
||||||
|
secretNamespace: <secret-namespace> # default
|
||||||
|
|
||||||
|
# secretsScope is identical to the secrets scope in the universalAuth field in this sample.
|
||||||
|
secretsScope:
|
||||||
|
projectSlug: your-project-slug
|
||||||
|
envSlug: prod
|
||||||
|
secretsPath: "/path"
|
||||||
|
recursive: true
|
||||||
|
|
||||||
# Azure Auth
|
# Azure Auth
|
||||||
azureAuth:
|
azureAuth:
|
||||||
identityId: <your-machine-identity-id>
|
identityId: <your-machine-identity-id>
|
||||||
|
8
k8-operator/config/samples/ldapAuthIdentitySecret.yaml
Normal file
8
k8-operator/config/samples/ldapAuthIdentitySecret.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: ldap-auth-credentials
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
username: <ldap-username>
|
||||||
|
password: <ldap-password>
|
@@ -85,6 +85,7 @@ func (r *InfisicalDynamicSecretReconciler) handleAuthentication(ctx context.Cont
|
|||||||
util.AuthStrategy.AZURE_MACHINE_IDENTITY: util.HandleAzureAuth,
|
util.AuthStrategy.AZURE_MACHINE_IDENTITY: util.HandleAzureAuth,
|
||||||
util.AuthStrategy.GCP_ID_TOKEN_MACHINE_IDENTITY: util.HandleGcpIdTokenAuth,
|
util.AuthStrategy.GCP_ID_TOKEN_MACHINE_IDENTITY: util.HandleGcpIdTokenAuth,
|
||||||
util.AuthStrategy.GCP_IAM_MACHINE_IDENTITY: util.HandleGcpIamAuth,
|
util.AuthStrategy.GCP_IAM_MACHINE_IDENTITY: util.HandleGcpIamAuth,
|
||||||
|
util.AuthStrategy.LDAP_MACHINE_IDENTITY: util.HandleLdapAuth,
|
||||||
}
|
}
|
||||||
|
|
||||||
for authStrategy, authHandler := range authStrategies {
|
for authStrategy, authHandler := range authStrategies {
|
||||||
|
@@ -32,6 +32,7 @@ func (r *InfisicalPushSecretReconciler) handleAuthentication(ctx context.Context
|
|||||||
util.AuthStrategy.AZURE_MACHINE_IDENTITY: util.HandleAzureAuth,
|
util.AuthStrategy.AZURE_MACHINE_IDENTITY: util.HandleAzureAuth,
|
||||||
util.AuthStrategy.GCP_ID_TOKEN_MACHINE_IDENTITY: util.HandleGcpIdTokenAuth,
|
util.AuthStrategy.GCP_ID_TOKEN_MACHINE_IDENTITY: util.HandleGcpIdTokenAuth,
|
||||||
util.AuthStrategy.GCP_IAM_MACHINE_IDENTITY: util.HandleGcpIamAuth,
|
util.AuthStrategy.GCP_IAM_MACHINE_IDENTITY: util.HandleGcpIamAuth,
|
||||||
|
util.AuthStrategy.LDAP_MACHINE_IDENTITY: util.HandleLdapAuth,
|
||||||
}
|
}
|
||||||
|
|
||||||
for authStrategy, authHandler := range authStrategies {
|
for authStrategy, authHandler := range authStrategies {
|
||||||
|
@@ -57,6 +57,7 @@ func (r *InfisicalSecretReconciler) handleAuthentication(ctx context.Context, in
|
|||||||
util.AuthStrategy.AZURE_MACHINE_IDENTITY: util.HandleAzureAuth,
|
util.AuthStrategy.AZURE_MACHINE_IDENTITY: util.HandleAzureAuth,
|
||||||
util.AuthStrategy.GCP_ID_TOKEN_MACHINE_IDENTITY: util.HandleGcpIdTokenAuth,
|
util.AuthStrategy.GCP_ID_TOKEN_MACHINE_IDENTITY: util.HandleGcpIdTokenAuth,
|
||||||
util.AuthStrategy.GCP_IAM_MACHINE_IDENTITY: util.HandleGcpIamAuth,
|
util.AuthStrategy.GCP_IAM_MACHINE_IDENTITY: util.HandleGcpIamAuth,
|
||||||
|
util.AuthStrategy.LDAP_MACHINE_IDENTITY: util.HandleLdapAuth,
|
||||||
}
|
}
|
||||||
|
|
||||||
for authStrategy, authHandler := range authStrategies {
|
for authStrategy, authHandler := range authStrategies {
|
||||||
|
@@ -5,7 +5,7 @@ go 1.21
|
|||||||
require (
|
require (
|
||||||
github.com/Masterminds/sprig/v3 v3.3.0
|
github.com/Masterminds/sprig/v3 v3.3.0
|
||||||
github.com/aws/smithy-go v1.20.3
|
github.com/aws/smithy-go v1.20.3
|
||||||
github.com/infisical/go-sdk v0.5.97
|
github.com/infisical/go-sdk v0.5.99
|
||||||
github.com/lestrrat-go/jwx/v2 v2.1.4
|
github.com/lestrrat-go/jwx/v2 v2.1.4
|
||||||
github.com/onsi/ginkgo/v2 v2.6.0
|
github.com/onsi/ginkgo/v2 v2.6.0
|
||||||
github.com/onsi/gomega v1.24.1
|
github.com/onsi/gomega v1.24.1
|
||||||
@@ -40,6 +40,7 @@ require (
|
|||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/goccy/go-json v0.10.3 // indirect
|
github.com/goccy/go-json v0.10.3 // indirect
|
||||||
|
github.com/gofrs/flock v0.8.1 // indirect
|
||||||
github.com/google/s2a-go v0.1.7 // indirect
|
github.com/google/s2a-go v0.1.7 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.12.5 // indirect
|
github.com/googleapis/gax-go/v2 v2.12.5 // indirect
|
||||||
@@ -52,9 +53,12 @@ require (
|
|||||||
github.com/lestrrat-go/option v1.0.1 // indirect
|
github.com/lestrrat-go/option v1.0.1 // indirect
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
|
github.com/oracle/oci-go-sdk/v65 v65.95.2 // indirect
|
||||||
github.com/segmentio/asm v1.2.0 // indirect
|
github.com/segmentio/asm v1.2.0 // indirect
|
||||||
github.com/shopspring/decimal v1.4.0 // indirect
|
github.com/shopspring/decimal v1.4.0 // indirect
|
||||||
|
github.com/sony/gobreaker v0.5.0 // indirect
|
||||||
github.com/spf13/cast v1.7.0 // indirect
|
github.com/spf13/cast v1.7.0 // indirect
|
||||||
|
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
|
||||||
|
@@ -152,6 +152,8 @@ github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96
|
|||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
|
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||||
|
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
@@ -237,6 +239,8 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
|||||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
github.com/infisical/go-sdk v0.5.97 h1:veOi6Hduda6emtwjdUI5SBg2qd2iDQc5xLKqZ15KSoM=
|
github.com/infisical/go-sdk v0.5.97 h1:veOi6Hduda6emtwjdUI5SBg2qd2iDQc5xLKqZ15KSoM=
|
||||||
github.com/infisical/go-sdk v0.5.97/go.mod h1:ExjqFLRz7LSpZpGluqDLvFl6dFBLq5LKyLW7GBaMAIs=
|
github.com/infisical/go-sdk v0.5.97/go.mod h1:ExjqFLRz7LSpZpGluqDLvFl6dFBLq5LKyLW7GBaMAIs=
|
||||||
|
github.com/infisical/go-sdk v0.5.99 h1:trvn7JhKYuSzDkc44h+yqToVjclkrRyP42t315k5kEE=
|
||||||
|
github.com/infisical/go-sdk v0.5.99/go.mod h1:j2D2a5WPNdKXDfHO+3y/TNyLWh5Aq9QYS7EcGI96LZI=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
@@ -303,6 +307,8 @@ github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc=
|
|||||||
github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc=
|
github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc=
|
||||||
github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
|
github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
|
||||||
github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM=
|
github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM=
|
||||||
|
github.com/oracle/oci-go-sdk/v65 v65.95.2 h1:0HJ0AgpLydp/DtvYrF2d4str2BjXOVAeNbuW7E07g94=
|
||||||
|
github.com/oracle/oci-go-sdk/v65 v65.95.2/go.mod h1:u6XRPsw9tPziBh76K7GrrRXPa8P8W3BQeqJ6ZZt9VLA=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
@@ -347,6 +353,8 @@ github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+D
|
|||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||||
|
github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg=
|
||||||
|
github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||||
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
||||||
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
@@ -365,8 +373,11 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
|
||||||
|
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
@@ -407,6 +418,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
|
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||||
@@ -551,6 +563,7 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
@@ -559,6 +572,7 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
|
|||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
|
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||||
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
||||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||||
|
@@ -6,11 +6,16 @@ type ServiceAccountDetails struct {
|
|||||||
PrivateKey string
|
PrivateKey string
|
||||||
}
|
}
|
||||||
|
|
||||||
type MachineIdentityDetails struct {
|
type UniversalAuthIdentityDetails struct {
|
||||||
ClientId string
|
ClientId string
|
||||||
ClientSecret string
|
ClientSecret string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LdapIdentityDetails struct {
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
|
}
|
||||||
|
|
||||||
type SingleEnvironmentVariable struct {
|
type SingleEnvironmentVariable struct {
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
|
@@ -88,6 +88,7 @@ var AuthStrategy = struct {
|
|||||||
AZURE_MACHINE_IDENTITY AuthStrategyType
|
AZURE_MACHINE_IDENTITY AuthStrategyType
|
||||||
GCP_ID_TOKEN_MACHINE_IDENTITY AuthStrategyType
|
GCP_ID_TOKEN_MACHINE_IDENTITY AuthStrategyType
|
||||||
GCP_IAM_MACHINE_IDENTITY AuthStrategyType
|
GCP_IAM_MACHINE_IDENTITY AuthStrategyType
|
||||||
|
LDAP_MACHINE_IDENTITY AuthStrategyType
|
||||||
}{
|
}{
|
||||||
SERVICE_TOKEN: "SERVICE_TOKEN",
|
SERVICE_TOKEN: "SERVICE_TOKEN",
|
||||||
SERVICE_ACCOUNT: "SERVICE_ACCOUNT",
|
SERVICE_ACCOUNT: "SERVICE_ACCOUNT",
|
||||||
@@ -97,6 +98,7 @@ var AuthStrategy = struct {
|
|||||||
AZURE_MACHINE_IDENTITY: "AZURE_MACHINE_IDENTITY",
|
AZURE_MACHINE_IDENTITY: "AZURE_MACHINE_IDENTITY",
|
||||||
GCP_ID_TOKEN_MACHINE_IDENTITY: "GCP_ID_TOKEN_MACHINE_IDENTITY",
|
GCP_ID_TOKEN_MACHINE_IDENTITY: "GCP_ID_TOKEN_MACHINE_IDENTITY",
|
||||||
GCP_IAM_MACHINE_IDENTITY: "GCP_IAM_MACHINE_IDENTITY",
|
GCP_IAM_MACHINE_IDENTITY: "GCP_IAM_MACHINE_IDENTITY",
|
||||||
|
LDAP_MACHINE_IDENTITY: "LDAP_MACHINE_IDENTITY",
|
||||||
}
|
}
|
||||||
|
|
||||||
type SecretCrdType string
|
type SecretCrdType string
|
||||||
@@ -188,6 +190,71 @@ func HandleUniversalAuth(ctx context.Context, reconcilerClient client.Client, se
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HandleLdapAuth(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface) (AuthenticationDetails, error) {
|
||||||
|
|
||||||
|
var ldapAuthSpec v1alpha1.LdapAuthDetails
|
||||||
|
|
||||||
|
switch secretCrd.Type {
|
||||||
|
case SecretCrd.INFISICAL_SECRET:
|
||||||
|
infisicalSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalSecret)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalSecret")
|
||||||
|
}
|
||||||
|
ldapAuthSpec = infisicalSecret.Spec.Authentication.LdapAuth
|
||||||
|
case SecretCrd.INFISICAL_PUSH_SECRET:
|
||||||
|
infisicalPushSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalPushSecret)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalPushSecret")
|
||||||
|
}
|
||||||
|
|
||||||
|
ldapAuthSpec = v1alpha1.LdapAuthDetails{
|
||||||
|
CredentialsRef: infisicalPushSecret.Spec.Authentication.LdapAuth.CredentialsRef,
|
||||||
|
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
|
||||||
|
IdentityID: infisicalPushSecret.Spec.Authentication.LdapAuth.IdentityID,
|
||||||
|
}
|
||||||
|
|
||||||
|
case SecretCrd.INFISICAL_DYNAMIC_SECRET:
|
||||||
|
infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret")
|
||||||
|
}
|
||||||
|
|
||||||
|
ldapAuthSpec = v1alpha1.LdapAuthDetails{
|
||||||
|
CredentialsRef: infisicalDynamicSecret.Spec.Authentication.LdapAuth.CredentialsRef,
|
||||||
|
SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{},
|
||||||
|
IdentityID: infisicalDynamicSecret.Spec.Authentication.LdapAuth.IdentityID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ldapAuthKubeSecret, err := GetInfisicalLdapAuthFromKubeSecret(ctx, reconcilerClient, v1alpha1.KubeSecretReference{
|
||||||
|
SecretNamespace: ldapAuthSpec.CredentialsRef.SecretNamespace,
|
||||||
|
SecretName: ldapAuthSpec.CredentialsRef.SecretName,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return AuthenticationDetails{}, fmt.Errorf("ReconcileInfisicalSecret: unable to get machine identity creds from kube secret [err=%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ldapAuthKubeSecret.Username == "" && ldapAuthKubeSecret.Password == "" {
|
||||||
|
return AuthenticationDetails{}, ErrAuthNotApplicable
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = infisicalClient.Auth().LdapAuthLogin(ldapAuthSpec.IdentityID, ldapAuthKubeSecret.Username, ldapAuthKubeSecret.Password)
|
||||||
|
if err != nil {
|
||||||
|
return AuthenticationDetails{}, fmt.Errorf("unable to login with machine identity credentials [err=%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return AuthenticationDetails{
|
||||||
|
AuthStrategy: AuthStrategy.LDAP_MACHINE_IDENTITY,
|
||||||
|
MachineIdentityScope: ldapAuthSpec.SecretsScope,
|
||||||
|
IsMachineIdentityAuth: true,
|
||||||
|
SecretType: secretCrd.Type,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func HandleKubernetesAuth(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface) (AuthenticationDetails, error) {
|
func HandleKubernetesAuth(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface) (AuthenticationDetails, error) {
|
||||||
var kubernetesAuthSpec v1alpha1.KubernetesAuthDetails
|
var kubernetesAuthSpec v1alpha1.KubernetesAuthDetails
|
||||||
|
|
||||||
|
@@ -18,6 +18,9 @@ import (
|
|||||||
const INFISICAL_MACHINE_IDENTITY_CLIENT_ID = "clientId"
|
const INFISICAL_MACHINE_IDENTITY_CLIENT_ID = "clientId"
|
||||||
const INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET = "clientSecret"
|
const INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET = "clientSecret"
|
||||||
|
|
||||||
|
const INFISICAL_MACHINE_IDENTITY_LDAP_USERNAME = "username"
|
||||||
|
const INFISICAL_MACHINE_IDENTITY_LDAP_PASSWORD = "password"
|
||||||
|
|
||||||
func GetKubeSecretByNamespacedName(ctx context.Context, reconcilerClient client.Client, namespacedName types.NamespacedName) (*corev1.Secret, error) {
|
func GetKubeSecretByNamespacedName(ctx context.Context, reconcilerClient client.Client, namespacedName types.NamespacedName) (*corev1.Secret, error) {
|
||||||
kubeSecret := &corev1.Secret{}
|
kubeSecret := &corev1.Secret{}
|
||||||
err := reconcilerClient.Get(ctx, namespacedName, kubeSecret)
|
err := reconcilerClient.Get(ctx, namespacedName, kubeSecret)
|
||||||
@@ -38,7 +41,7 @@ func GetKubeConfigMapByNamespacedName(ctx context.Context, reconcilerClient clie
|
|||||||
return kubeConfigMap, err
|
return kubeConfigMap, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetInfisicalUniversalAuthFromKubeSecret(ctx context.Context, reconcilerClient client.Client, universalAuthRef v1alpha1.KubeSecretReference) (machineIdentityDetails model.MachineIdentityDetails, err error) {
|
func GetInfisicalUniversalAuthFromKubeSecret(ctx context.Context, reconcilerClient client.Client, universalAuthRef v1alpha1.KubeSecretReference) (machineIdentityDetails model.UniversalAuthIdentityDetails, err error) {
|
||||||
|
|
||||||
universalAuthCredsFromKubeSecret, err := GetKubeSecretByNamespacedName(ctx, reconcilerClient, types.NamespacedName{
|
universalAuthCredsFromKubeSecret, err := GetKubeSecretByNamespacedName(ctx, reconcilerClient, types.NamespacedName{
|
||||||
Namespace: universalAuthRef.SecretNamespace,
|
Namespace: universalAuthRef.SecretNamespace,
|
||||||
@@ -48,17 +51,39 @@ func GetInfisicalUniversalAuthFromKubeSecret(ctx context.Context, reconcilerClie
|
|||||||
})
|
})
|
||||||
|
|
||||||
if k8Errors.IsNotFound(err) {
|
if k8Errors.IsNotFound(err) {
|
||||||
return model.MachineIdentityDetails{}, nil
|
return model.UniversalAuthIdentityDetails{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return model.MachineIdentityDetails{}, fmt.Errorf("something went wrong when fetching your machine identity credentials [err=%s]", err)
|
return model.UniversalAuthIdentityDetails{}, fmt.Errorf("something went wrong when fetching your machine identity credentials [err=%s]", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientIdFromSecret := universalAuthCredsFromKubeSecret.Data[INFISICAL_MACHINE_IDENTITY_CLIENT_ID]
|
clientIdFromSecret := universalAuthCredsFromKubeSecret.Data[INFISICAL_MACHINE_IDENTITY_CLIENT_ID]
|
||||||
clientSecretFromSecret := universalAuthCredsFromKubeSecret.Data[INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET]
|
clientSecretFromSecret := universalAuthCredsFromKubeSecret.Data[INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET]
|
||||||
|
|
||||||
return model.MachineIdentityDetails{ClientId: string(clientIdFromSecret), ClientSecret: string(clientSecretFromSecret)}, nil
|
return model.UniversalAuthIdentityDetails{ClientId: string(clientIdFromSecret), ClientSecret: string(clientSecretFromSecret)}, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetInfisicalLdapAuthFromKubeSecret(ctx context.Context, reconcilerClient client.Client, ldapAuthRef v1alpha1.KubeSecretReference) (machineIdentityDetails model.LdapIdentityDetails, err error) {
|
||||||
|
|
||||||
|
ldapAuthCredsFromKubeSecret, err := GetKubeSecretByNamespacedName(ctx, reconcilerClient, types.NamespacedName{
|
||||||
|
Namespace: ldapAuthRef.SecretNamespace,
|
||||||
|
Name: ldapAuthRef.SecretName,
|
||||||
|
})
|
||||||
|
|
||||||
|
if k8Errors.IsNotFound(err) {
|
||||||
|
return model.LdapIdentityDetails{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return model.LdapIdentityDetails{}, fmt.Errorf("something went wrong when fetching your machine identity credentials [err=%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
usernameFromSecret := ldapAuthCredsFromKubeSecret.Data[INFISICAL_MACHINE_IDENTITY_LDAP_USERNAME]
|
||||||
|
passwordFromSecret := ldapAuthCredsFromKubeSecret.Data[INFISICAL_MACHINE_IDENTITY_LDAP_PASSWORD]
|
||||||
|
|
||||||
|
return model.LdapIdentityDetails{Username: string(usernameFromSecret), Password: string(passwordFromSecret)}, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user