mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-15 10:29:43 +00:00
Compare commits
5 Commits
patch-5
...
infisical/
Author | SHA1 | Date | |
---|---|---|---|
5941e8e836 | |||
80e50d13ec | |||
99c8dda4e1 | |||
14c8e3fa3b | |||
7aa3cb53a2 |
@ -17,12 +17,12 @@ export const getSecretApprovalRequestCount = async (req: Request, res: Response)
|
||||
} = await validateRequest(reqValidator.getSecretApprovalRequestCount, req);
|
||||
|
||||
if (!(req.authData.authPayload instanceof User)) return;
|
||||
|
||||
|
||||
const membership = await Membership.findOne({
|
||||
user: req.authData.authPayload._id,
|
||||
workspace: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
|
||||
|
||||
if (!membership) throw UnauthorizedRequestError();
|
||||
|
||||
const approvalRequestCount = await SecretApprovalRequest.aggregate([
|
||||
@ -73,12 +73,12 @@ export const getSecretApprovalRequests = async (req: Request, res: Response) =>
|
||||
} = await validateRequest(reqValidator.getSecretApprovalRequests, req);
|
||||
|
||||
if (!(req.authData.authPayload instanceof User)) return;
|
||||
|
||||
|
||||
const membership = await Membership.findOne({
|
||||
user: req.authData.authPayload._id,
|
||||
workspace: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
|
||||
|
||||
if (!membership) throw UnauthorizedRequestError();
|
||||
|
||||
const query = {
|
||||
@ -168,13 +168,13 @@ export const getSecretApprovalRequestDetails = async (req: Request, res: Respons
|
||||
user: req.authData.authPayload._id,
|
||||
workspace: secretApprovalRequest.workspace
|
||||
});
|
||||
|
||||
|
||||
if (!membership) throw UnauthorizedRequestError();
|
||||
|
||||
// allow to fetch only if its admin or is the committer or approver
|
||||
if (
|
||||
membership.role !== "admin" &&
|
||||
secretApprovalRequest.committer !== membership.id &&
|
||||
!secretApprovalRequest.committer.equals(membership.id) &&
|
||||
!secretApprovalRequest.policy.approvers.find(
|
||||
(approverId) => approverId.toString() === membership._id.toString()
|
||||
)
|
||||
@ -215,7 +215,7 @@ export const updateSecretApprovalReviewStatus = async (req: Request, res: Respon
|
||||
user: req.authData.authPayload._id,
|
||||
workspace: secretApprovalRequest.workspace
|
||||
});
|
||||
|
||||
|
||||
if (!membership) throw UnauthorizedRequestError();
|
||||
|
||||
if (
|
||||
@ -257,7 +257,7 @@ export const mergeSecretApprovalRequest = async (req: Request, res: Response) =>
|
||||
user: req.authData.authPayload._id,
|
||||
workspace: secretApprovalRequest.workspace
|
||||
});
|
||||
|
||||
|
||||
if (!membership) throw UnauthorizedRequestError();
|
||||
|
||||
if (
|
||||
@ -307,7 +307,7 @@ export const updateSecretApprovalRequestStatus = async (req: Request, res: Respo
|
||||
user: req.authData.authPayload._id,
|
||||
workspace: secretApprovalRequest.workspace
|
||||
});
|
||||
|
||||
|
||||
if (!membership) throw UnauthorizedRequestError();
|
||||
|
||||
if (
|
||||
|
@ -10,97 +10,97 @@ description: "Configure Azure SAML for Infisical SSO"
|
||||
then you should contact team@infisical.com to purchase an enterprise license to use it.
|
||||
</Info>
|
||||
|
||||
1. In Infisical, head over to your organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**.
|
||||
Next, copy the **Reply URL (Assertion Consumer Service URL)** and **Identifier (Entity ID)** to use when configuring the Azure SAML application.
|
||||
<Steps>
|
||||
<Step title="Prepare the SAML SSO configuration in Infisical">
|
||||
In Infisical, head over to your organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**.
|
||||
|
||||

|
||||
Next, copy the **Reply URL (Assertion Consumer Service URL)** and **Identifier (Entity ID)** to use when configuring the Azure SAML application.
|
||||
|
||||
2. In the Azure Portal, navigate to the Azure Active Directory and select **Enterprise applications**. On this screen, select
|
||||
**+ New application**.
|
||||

|
||||
</Step>
|
||||
<Step title="Create a SAML application in Azure">
|
||||
In the Azure Portal, navigate to the Azure Active Directory and select **Enterprise applications**. On this screen, select **+ New application**.
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
On the next screen, press the **+ Create your own application** button.
|
||||
Give the application a unique name like Infisical; choose the "Integrate any other application you don't find in the gallery (Non-gallery)"
|
||||
option and hit the **Create** button.
|
||||
|
||||
2. On the next screen, press the **+ Create your own application** button.
|
||||
Give the application a unique name like Infisical; choose the "Integrate any other application you don't find in the gallery (Non-gallery)"
|
||||
option and hit the **Create** button.
|
||||

|
||||
|
||||

|
||||
On the application overview screen, select **Single sign-on** from the left sidebar. From there, select the **SAML** single sign-on method.
|
||||
|
||||
3. On the application overview screen, select **Single sign-on** from the left sidebar. From there,
|
||||
select the **SAML** single sign-on method.
|
||||

|
||||
|
||||

|
||||
Next, select **Edit** in the **Basic SAML Configuration** section and add/set the **Identifier (Entity ID)** to **Entity ID** and add/set the **Reply URL (Assertion Consumer Service URL)** to **ACS URL** from step 1.
|
||||
|
||||
4. Next, select **Edit** in the **Basic SAML Configuration** section and add/set the **Identifier (Entity ID)**
|
||||
to **Entity ID** and add/set the **Reply URL (Assertion Consumer Service URL)** to **ACS URL** from step 1.
|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
<Note>
|
||||
If you're self-hosting Infisical, then you will want to replace
|
||||
`https://app.infisical.com` with your own domain.
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
If you're self-hosting Infisical, then you will want to replace
|
||||
`https://app.infisical.com` with your own domain.
|
||||
</Note>
|
||||
Back in the **Set up Single Sign-On with SAML** screen, select **Edit** in the **Attributes & Claims** section and configure the following map:
|
||||
|
||||
5. Back in the **Set up Single Sign-On with SAML** screen, select **Edit** in the **Attributes & Claims** section and configure the following map:
|
||||
- `email -> user.userprinciplename`
|
||||
- `firstName -> user.firstName`
|
||||
- `lastName -> user.lastName`
|
||||
|
||||
- `email -> user.userprinciplename`
|
||||
- `firstName -> user.firstName`
|
||||
- `lastName -> user.lastName`
|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
Back in the **Set up Single Sign-On with SAML** screen, select **Edit** in the **SAML Certificates** section and set the **Signing Option** field to **Sign SAML response and assertion**.
|
||||
|
||||
6. Back in the **Set up Single Sign-On with SAML** screen, select **Edit** in the **SAML Certificates** section and set the **Signing Option** field to **Sign SAML response and assertion**.
|
||||

|
||||
|
||||

|
||||

|
||||
</Step>
|
||||
<Step title="Retrieve Identity Provider (IdP) Information from Okta">
|
||||
In the **Set up Single Sign-On with SAML** screen, copy the **Login URL** and **SAML Certificate** to use when finishing configuring Azure SAML in Infisical.
|
||||
|
||||

|
||||

|
||||
|
||||
7. Get IdP values:
|
||||
In the **Properties** screen, copy the **Application ID** to use when finishing configuring Azure SAML in Infisical.
|
||||
|
||||
In the **Set up Single Sign-On with SAML** screen, copy the **Login URL** and **SAML Certificate** to use when finishing configuring Azure SAML in Infisical.
|
||||

|
||||
</Step>
|
||||
<Step title="Finish configuring SAML in Infisical">
|
||||
Back in Infisical, set **Login URL**, **Azure Application ID**, and **SAML Certificate** from step 3. Once you've done that, press **Update** to complete the required configuration.
|
||||
|
||||

|
||||

|
||||
|
||||
In the **Properties** screen, copy the **Application ID** to use when finishing configuring Azure SAML in Infisical.
|
||||
<Note>
|
||||
When pasting the certificate into Infisical, you'll want to retain `-----BEGIN
|
||||
CERTIFICATE-----` and `-----END CERTIFICATE-----` at the first and last line
|
||||
of the text area respectively.
|
||||
|
||||

|
||||
Having trouble?, try copying the X509 certificate information from the Federation Metadata XML file in Azure.
|
||||
|
||||
Back in Infisical, set **Login URL**, **Azure Application ID**, and **SAML Certificate** from above. Once you've done that, press **Update** to complete the required configuration.
|
||||
</Note>
|
||||
</Step>
|
||||
<Step title="Assign users in Azure to the application">
|
||||
Back in Azure, navigate to the **Users and groups** tab and select **+ Add user/group** to assign access to the login with SSO application on a user or group-level.
|
||||
|
||||

|
||||
</Step>
|
||||
<Step title="Enable SAML SSO in Infisical">
|
||||
Enabling SAML SSO enforces all members in your organization to only be able to log into Infisical via Azure.
|
||||
|
||||

|
||||
|
||||
<Note>
|
||||
When pasting the certificate into Infisical, you'll want to retain `-----BEGIN
|
||||
CERTIFICATE-----` and `-----END CERTIFICATE-----` at the first and last line
|
||||
of the text area respectively.
|
||||
|
||||
Having trouble?, try copying the X509 certificate information from the Federation Metadata XML file in Azure.
|
||||
|
||||
</Note>
|
||||
|
||||
7. Assignments
|
||||
|
||||
Back in Azure, navigate to the **Users and groups** tab and select **+ Add user/group** to assign access to the login with SSO application on a user or group-level.
|
||||

|
||||
|
||||
8. Return to Infisical and enable SAML SSO.
|
||||
|
||||
Enabling SAML SSO enforces all members in your organization to only be able to log into Infisical via Azure.
|
||||
|
||||

|
||||

|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
If you're configuring SAML SSO on a self-hosted instance of Infisical, make sure to
|
||||
set the `JWT_PROVIDER_AUTH_SECRET` and `SITE_URL` environment variable for it to work:
|
||||
set the `AUTH_SECRET` and `SITE_URL` environment variable for it to work:
|
||||
|
||||
- `JWT_PROVIDER_AUTH_SECRET`: This is secret key used for signing and verifying JWT. This could be a randomly-generated 256-bit hex string.
|
||||
- `AUTH_SECRET`: A secret key used for signing and verifying JWT. This can be a random 32-byte base64 string generated with `openssl rand -base64 32`.
|
||||
- `SITE_URL`: The URL of your self-hosted instance of Infisical - should be an absolute URL including the protocol (e.g. https://app.infisical.com)
|
||||
</Note>
|
||||
|
||||
|
||||
</Note>
|
@ -5,38 +5,39 @@ description: "Configure GitHub SSO for Infisical"
|
||||
|
||||
Using GitHub SSO on a self-hosted instance of Infisical requires configuring an OAuth2 application in GitHub and registering your instance with it.
|
||||
|
||||
## Create an OAuth application in GitHub
|
||||
<Steps>
|
||||
<Step title="Create an OAuth application in GitHub">
|
||||
Navigate to your user Settings > Developer settings > OAuth Apps to create a new GitHub OAuth application.
|
||||
|
||||
Navigate to your user Settings > Developer settings > OAuth Apps to create a new GitHub OAuth application.
|
||||

|
||||

|
||||

|
||||
|
||||

|
||||

|
||||

|
||||
Create the OAuth application. As part of the form, set the **Homepage URL** to your self-hosted domain `https://your-domain.com`
|
||||
and the **Authorization callback URL** to `https://your-domain.com/api/v1/sso/github`.
|
||||
|
||||
Create the OAuth application. As part of the form, set the **Homepage URL** to your self-hosted domain `https://your-domain.com`
|
||||
and the **Authorization callback URL** to `https://your-domain.com/api/v1/sso/github`.
|
||||

|
||||
|
||||

|
||||
<Note>
|
||||
If you have a GitHub organization, you can create an OAuth application under it
|
||||
in your organization Settings > Developer settings > OAuth Apps > New Org OAuth App.
|
||||
</Note>
|
||||
</Step>
|
||||
<Step title="Add your OAuth application credentials to Infisical">
|
||||
Obtain the **Client ID** and generate a new **Client Secret** for your GitHub OAuth application.
|
||||
|
||||
<Note>
|
||||
If you have a GitHub organization, you can create an OAuth application under it
|
||||
in your organization Settings > Developer settings > OAuth Apps > New Org OAuth App.
|
||||
</Note>
|
||||

|
||||
|
||||
## Add your OAuth application credentials to Infisical
|
||||
Back in your Infisical instance, make sure to set the following environment variables:
|
||||
|
||||
Obtain the **Client ID** and generate a new **Client Secret** for your GitHub OAuth application.
|
||||
|
||||

|
||||
|
||||
Back in your Infisical instance, make sure to set the following environment variables:
|
||||
|
||||
- `CLIENT_ID_GITHUB_LOGIN`: The **Client ID** of your GitHub OAuth application.
|
||||
- `CLIENT_SECRET_GITHUB_LOGIN`: The **Client Secret** of your GitHub OAuth application.
|
||||
- `JWT_PROVIDER_AUTH_SECRET`: A secret key used for signing and verifying JWT. This could be a randomly-generated 256-bit hex string.
|
||||
- `SITE_URL`: The URL of your self-hosted instance of Infisical - should be an absolute URL including the protocol (e.g. https://app.infisical.com)
|
||||
|
||||
Once added, restart your Infisical instance and log in with GitHub.
|
||||
- `CLIENT_ID_GITHUB_LOGIN`: The **Client ID** of your GitHub OAuth application.
|
||||
- `CLIENT_SECRET_GITHUB_LOGIN`: The **Client Secret** of your GitHub OAuth application.
|
||||
- `AUTH_SECRET`: A secret key used for signing and verifying JWT. This can be a random 32-byte base64 string generated with `openssl rand -base64 32`.
|
||||
- `SITE_URL`: The URL of your self-hosted instance of Infisical - should be an absolute URL including the protocol (e.g. https://app.infisical.com)
|
||||
|
||||
Once added, restart your Infisical instance and log in with GitHub.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## FAQ
|
||||
|
||||
@ -45,7 +46,7 @@ Once added, restart your Infisical instance and log in with GitHub.
|
||||
It is likely that you have misconfigured your self-hosted instance of Infisical. You should:
|
||||
|
||||
- Check that you have set the `CLIENT_ID_GITHUB_LOGIN`, `CLIENT_SECRET_GITHUB_LOGIN`,
|
||||
`JWT_PROVIDER_AUTH_SECRET`, and `SITE_URL` environment variables.
|
||||
`AUTH_SECRET`, and `SITE_URL` environment variables.
|
||||
- Check that the **Authorization callback URL** specified in GitHub matches the `SITE_URL` environment variable.
|
||||
For example, if the former is `https://app.infisical.com/api/v1/sso/github` then the latter should be `https://app.infisical.com`.
|
||||
</Accordion>
|
||||
|
@ -5,38 +5,39 @@ description: "Configure GitLab SSO for Infisical"
|
||||
|
||||
Using GitLab SSO on a self-hosted instance of Infisical requires configuring an OAuth application in GitLab and registering your instance with it.
|
||||
|
||||
## Create an OAuth application in GitLab
|
||||
<Steps>
|
||||
<Step title="Create an OAuth application in GitLab">
|
||||
Navigate to your user Settings > Applications to create a new GitLab application.
|
||||
|
||||
Navigate to your user Settings > Applications to create a new GitLab application.
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
Create the application. As part of the form, set the **Redirect URI** to `https://your-domain.com/api/v1/sso/gitlab`.
|
||||
Note that only `read_user` is required as part of the **Scopes** configuration.
|
||||
|
||||
Create the application. As part of the form, set the **Redirect URI** to `https://your-domain.com/api/v1/sso/gitlab`.
|
||||
Note that only `read_user` is required as part of the **Scopes** configuration.
|
||||

|
||||
|
||||

|
||||
<Note>
|
||||
If you have a GitLab group, you can create an OAuth application under it
|
||||
in your group Settings > Applications.
|
||||
</Note>
|
||||
</Step>
|
||||
<Step title="Add your OAuth application credentials to Infisical">
|
||||
Obtain the **Application ID** and **Secret** for your GitLab application.
|
||||
|
||||
<Note>
|
||||
If you have a GitLab group, you can create an OAuth application under it
|
||||
in your group Settings > Applications.
|
||||
</Note>
|
||||

|
||||
|
||||
## Add your OAuth application credentials to Infisical
|
||||
Back in your Infisical instance, make sure to set the following environment variables:
|
||||
|
||||
Obtain the **Application ID** and **Secret** for your GitLab application.
|
||||
|
||||

|
||||
|
||||
Back in your Infisical instance, make sure to set the following environment variables:
|
||||
|
||||
- `CLIENT_ID_GITLAB_LOGIN`: The **Client ID** of your GitLab application.
|
||||
- `CLIENT_SECRET_GITLAB_LOGIN`: The **Secret** of your GitLab application.
|
||||
- (optional) `URL_GITLAB_LOGIN`: The URL of your self-hosted instance of GitLab where the OAuth application is registered. If no URL is passed in, this will default to `https://gitlab.com`.
|
||||
- `JWT_PROVIDER_AUTH_SECRET`: A secret key used for signing and verifying JWT. This could be a randomly-generated 256-bit hex string.
|
||||
- `SITE_URL`: The URL of your self-hosted instance of Infisical - should be an absolute URL including the protocol (e.g. https://app.infisical.com)
|
||||
|
||||
Once added, restart your Infisical instance and log in with GitLab.
|
||||
- `CLIENT_ID_GITLAB_LOGIN`: The **Client ID** of your GitLab application.
|
||||
- `CLIENT_SECRET_GITLAB_LOGIN`: The **Secret** of your GitLab application.
|
||||
- (optional) `URL_GITLAB_LOGIN`: The URL of your self-hosted instance of GitLab where the OAuth application is registered. If no URL is passed in, this will default to `https://gitlab.com`.
|
||||
- `AUTH_SECRET`: A secret key used for signing and verifying JWT. This can be a random 32-byte base64 string generated with `openssl rand -base64 32`.
|
||||
- `SITE_URL`: The URL of your self-hosted instance of Infisical - should be an absolute URL including the protocol (e.g. https://app.infisical.com)
|
||||
|
||||
Once added, restart your Infisical instance and log in with GitLab.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## FAQ
|
||||
|
||||
@ -45,7 +46,7 @@ Once added, restart your Infisical instance and log in with GitLab.
|
||||
It is likely that you have misconfigured your self-hosted instance of Infisical. You should:
|
||||
|
||||
- Check that you have set the `CLIENT_ID_GITLAB_LOGIN`, `CLIENT_SECRET_GITLAB_LOGIN`,
|
||||
`JWT_PROVIDER_AUTH_SECRET`, and `SITE_URL` environment variables.
|
||||
`AUTH_SECRET`, and `SITE_URL` environment variables.
|
||||
- Check that the **Redirect URI** specified in GitLab matches the `SITE_URL` environment variable.
|
||||
For example, if the former is `https://app.infisical.com/api/v1/sso/gitlab` then the latter should be `https://app.infisical.com`.
|
||||
</Accordion>
|
||||
|
@ -5,31 +5,32 @@ description: "Configure Google SSO for Infisical"
|
||||
|
||||
Using Google SSO on a self-hosted instance of Infisical requires configuring an OAuth2 application in GCP and registering your instance with it.
|
||||
|
||||
## Create an OAuth2 application in GCP
|
||||
<Steps>
|
||||
<Step title="Create an OAuth2 application in GCP">
|
||||
Navigate to your project API & Services > Credentials to create a new OAuth2 application.
|
||||
|
||||

|
||||

|
||||
|
||||
Navigate to your project API & Services > Credentials to create a new OAuth2 application.
|
||||
|
||||

|
||||

|
||||
Create the application. As part of the form, add to **Authorized redirect URIs**: `https://your-domain.com/api/v1/sso/google`.
|
||||
|
||||
Create the application. As part of the form, add to **Authorized redirect URIs**: `https://your-domain.com/api/v1/sso/google`.
|
||||

|
||||
</Step>
|
||||
<Step title="Add your OAuth2 application credentials to Infisical">
|
||||
Obtain the **Client ID** and **Client Secret** for your GCP OAuth2 application.
|
||||
|
||||

|
||||

|
||||
|
||||
Back in your Infisical instance, make sure to set the following environment variables:
|
||||
|
||||
## Add your OAuth2 application credentials to Infisical
|
||||
|
||||
Obtain the **Client ID** and **Client Secret** for your GCP OAuth2 application.
|
||||
|
||||

|
||||
|
||||
Back in your Infisical instance, make sure to set the following environment variables:
|
||||
|
||||
- `CLIENT_ID_GOOGLE_LOGIN`: The **Client ID** of your GCP OAuth2 application.
|
||||
- `CLIENT_SECRET_GOOGLE_LOGIN`: The **Client Secret** of your GCP OAuth2 application.
|
||||
- `JWT_PROVIDER_AUTH_SECRET`: A secret key used for signing and verifying JWT. This could be a randomly-generated 256-bit hex string.
|
||||
- `SITE_URL`: The URL of your self-hosted instance of Infisical - should be an absolute URL including the protocol (e.g. https://app.infisical.com)
|
||||
|
||||
Once added, restart your Infisical instance and log in with Google
|
||||
- `CLIENT_ID_GOOGLE_LOGIN`: The **Client ID** of your GCP OAuth2 application.
|
||||
- `CLIENT_SECRET_GOOGLE_LOGIN`: The **Client Secret** of your GCP OAuth2 application.
|
||||
- `AUTH_SECRET`: A secret key used for signing and verifying JWT. This can be a random 32-byte base64 string generated with `openssl rand -base64 32`.
|
||||
- `SITE_URL`: The URL of your self-hosted instance of Infisical - should be an absolute URL including the protocol (e.g. https://app.infisical.com)
|
||||
|
||||
Once added, restart your Infisical instance and log in with Google
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## FAQ
|
||||
|
||||
@ -38,7 +39,7 @@ Once added, restart your Infisical instance and log in with Google
|
||||
It is likely that you have misconfigured your self-hosted instance of Infisical. You should:
|
||||
|
||||
- Check that you have set the `CLIENT_ID_GOOGLE_LOGIN`, `CLIENT_SECRET_GOOGLE_LOGIN`,
|
||||
`JWT_PROVIDER_AUTH_SECRET`, and `SITE_URL` environment variables.
|
||||
`AUTH_SECRET`, and `SITE_URL` environment variables.
|
||||
- Check that the **Authorized redirect URI** specified in GCP matches the `SITE_URL` environment variable.
|
||||
For example, if the former is `https://app.infisical.com/api/v1/sso/google` then the latter should be `https://app.infisical.com`.
|
||||
</Accordion>
|
||||
|
@ -10,73 +10,77 @@ description: "Configure JumpCloud SAML for Infisical SSO"
|
||||
then you should contact team@infisical.com to purchase an enterprise license to use it.
|
||||
</Info>
|
||||
|
||||
1. In Infisical, head over to your organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**.
|
||||
Next, copy the **ACS URL** and **SP Entity ID** to use when configuring the JumpCloud SAML application.
|
||||
<Steps>
|
||||
<Step title="Prepare the SAML SSO configuration in Infisical">
|
||||
In Infisical, head over to your organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**.
|
||||
|
||||

|
||||
Next, copy the **ACS URL** and **SP Entity ID** to use when configuring the JumpCloud SAML application.
|
||||
|
||||
2. In the JumpCloud Admin Portal, navigate to User Authentication > SSO and create an application. If this is your first application, select **Get Started**;
|
||||
if not, select **+Add New Application**
|
||||

|
||||
</Step>
|
||||
<Step title="Create a SAML application in JumpCloud">
|
||||
2.1. In the JumpCloud Admin Portal, navigate to User Authentication > SSO and create an application. If this is your first application, select **Get Started**; if not, select **+Add New Application**
|
||||
|
||||

|
||||

|
||||
|
||||
3. Next, select **Custom SAML App** to open up the **New SSO** dialog.
|
||||
2.2. Next, select **Custom SAML App** to open up the **New SSO** dialog.
|
||||
|
||||

|
||||

|
||||
|
||||
4. In the **General Info** tab, give the application a unique name like Infisical.
|
||||
2.3. In the **General Info** tab, give the application a unique name like Infisical.
|
||||
|
||||

|
||||

|
||||
|
||||
5. In the **SSO** tab, set the **SP Entity ID** and **ACS URL** from step 1; set the **IdP Entity ID** to the same value as the **SP Entity ID**.
|
||||
2.4. In the **SSO** tab, set the **SP Entity ID** and **ACS URL** from step 1; set the **IdP Entity ID** to the same value as the **SP Entity ID**.
|
||||
|
||||

|
||||

|
||||
|
||||
6. On the same tab, check the **Sign Assertion** checkbox and fill the **IDP URL** to something unique.
|
||||
Copy the **IDP URL** to use when finishing configuring the JumpCloud SAML in Infisical.
|
||||
2.5. On the same tab, check the **Sign Assertion** checkbox and fill the **IDP URL** to something unique.
|
||||
Copy the **IDP URL** to use when finishing configuring the JumpCloud SAML in Infisical.
|
||||
|
||||

|
||||

|
||||
|
||||
7. On the same tab, in the **Attributes** section, configure the following map:
|
||||
2.6. On the same tab, in the **Attributes** section, configure the following map:
|
||||
|
||||
- `email -> email`
|
||||
- `firstName -> firstname`
|
||||
- `lastName -> lastname`
|
||||
- `email -> email`
|
||||
- `firstName -> firstname`
|
||||
- `lastName -> lastname`
|
||||
|
||||

|
||||

|
||||
|
||||
Finally press activate to create the SAML application.
|
||||
Finally press activate to create the SAML application.
|
||||
|
||||
8. Next, select the newly created SAML application and select **Download certificate** under the **IDP Certificate Valid** dropdown
|
||||
2.7. Next, select the newly created SAML application and select **Download certificate** under the **IDP Certificate Valid** dropdown
|
||||
|
||||

|
||||

|
||||
</Step>
|
||||
<Step title="Finish configuring SAML in Infisical">
|
||||
Back in Infisical, set the **IDP URL** from step 2.5 and the **IdP Entity ID** from step 2.4. Also, paste the certificate from the previous step.
|
||||
|
||||
9. Back in Infisical, set the **IDP URL** from step 6 and the **IdP Entity ID** from step 5. Also, paste the certificate from the previous step.
|
||||

|
||||
|
||||

|
||||
<Note>
|
||||
When pasting the certificate into Infisical, you'll want to retain `-----BEGIN
|
||||
CERTIFICATE-----` and `-----END CERTIFICATE-----` at the first and last line
|
||||
of the text area respectively.
|
||||
</Note>
|
||||
</Step>
|
||||
<Step title="Assign users in JumpCloud to the application">
|
||||
Back in JumpCloud, navigate to the **User Groups** tab and assign users to the newly created application.
|
||||
|
||||
<Note>
|
||||
When pasting the certificate into Infisical, you'll want to retain `-----BEGIN
|
||||
CERTIFICATE-----` and `-----END CERTIFICATE-----` at the first and last line
|
||||
of the text area respectively.
|
||||
</Note>
|
||||

|
||||
</Step>
|
||||
<Step title="Enable SAML SSO in Infisical">
|
||||
Enabling SAML SSO enforces all members in your organization to only be able to log into Infisical via JumpCloud.
|
||||
|
||||
10. Assignments
|
||||
|
||||
Back in JumpCloud, navigate to the **User Groups** tab and assign users to the newly created application.
|
||||
|
||||

|
||||
|
||||
11. Return to Infisical and enable SAML SSO.
|
||||
|
||||
Enabling SAML SSO enforces all members in your organization to only be able to log into Infisical via JumpCloud.
|
||||
|
||||

|
||||

|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
If you're configuring SAML SSO on a self-hosted instance of Infisical, make sure to
|
||||
set the `JWT_PROVIDER_AUTH_SECRET` and `SITE_URL` environment variable for it to work:
|
||||
set the `AUTH_SECRET` and `SITE_URL` environment variable for it to work:
|
||||
|
||||
- `JWT_PROVIDER_AUTH_SECRET`: This is secret key used for signing and verifying JWT. This could be a randomly-generated 256-bit hex string.
|
||||
- `AUTH_SECRET`: A secret key used for signing and verifying JWT. This can be a random 32-byte base64 string generated with `openssl rand -base64 32`.
|
||||
- `SITE_URL`: The URL of your self-hosted instance of Infisical - should be an absolute URL including the protocol (e.g. https://app.infisical.com)
|
||||
</Note>
|
||||
|
@ -10,78 +10,80 @@ description: "Configure Okta SAML 2.0 for Infisical SSO"
|
||||
then you should contact team@infisical.com to purchase an enterprise license to use it.
|
||||
</Info>
|
||||
|
||||
1. In Infisical, head over to your organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**.
|
||||
Next, copy the **Single sign-on URL** and **Audience URI (SP Entity ID)** to use when configuring the Okta SAML 2.0 application.
|
||||
<Steps>
|
||||
<Step title="Prepare the SAML SSO configuration in Infisical">
|
||||
In Infisical, head over to your organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**.
|
||||
|
||||
Next, copy the **Single sign-on URL** and **Audience URI (SP Entity ID)** to use when configuring the Okta SAML 2.0 application.
|
||||

|
||||
</Step>
|
||||
<Step title="Create a SAML application in Okta">
|
||||
In the Okta Admin Portal, select Applications > Applications from the navigation. On the Applications screen, select the **Create App Integration**
|
||||
button.
|
||||
|
||||

|
||||

|
||||
|
||||
In the Create a New Application Integration dialog, select the **SAML 2.0** radio button:
|
||||
|
||||
2. In the Okta Admin Portal, select Applications > Applications from the
|
||||
navigation. On the Applications screen, select the **Create App Integration**
|
||||
button.
|
||||

|
||||
|
||||
On the General Settings screen, give the application a unique name like Infisical and select **Next**.
|
||||
|
||||

|
||||
|
||||
On the Configure SAML screen, set the **Single sign-on URL** and **Audience URI (SP Entity ID)** from step 1.
|
||||
|
||||

|
||||

|
||||
|
||||
<Note>
|
||||
If you're self-hosting Infisical, then you will want to replace
|
||||
`https://app.infisical.com` with your own domain.
|
||||
</Note>
|
||||
|
||||
Also on the Configure SAML screen, configure the **Attribute Statements** to map:
|
||||
|
||||
3. In the Create a New Application Integration dialog, select the **SAML 2.0** radio button:
|
||||
- `id -> user.id`,
|
||||
- `email -> user.email`,
|
||||
- `firstName -> user.firstName`
|
||||
- `lastName -> user.lastName`
|
||||
|
||||

|
||||

|
||||
|
||||
4. On the General Settings screen, give the application a unique name like Infisical and select **Next**.
|
||||
Once configured, select **Next** to proceed to the Feedback screen and select **Finish**.
|
||||
</Step>
|
||||
<Step title="Retrieve Identity Provider (IdP) Information from Okta">
|
||||
Once your application is created, select the **Sign On** tab for the app and select the **View Setup Instructions** button located on the right side of the screen:
|
||||
|
||||

|
||||

|
||||
|
||||
5. On the Configure SAML screen, set the **Single sign-on URL** and **Audience URI (SP Entity ID)** from step 1.
|
||||
Copy the **Identity Provider Single Sign-On URL**, the **Identity Provider Issuer**, and the **X.509 Certificate** to use when finishing configuring Okta SAML in Infisical.
|
||||
|
||||

|
||||

|
||||
</Step>
|
||||
<Step title="Finish configuring SAML in Infisical">
|
||||
Back in Infisical, set **Identity Provider Single Sign-On URL**, **Identity Provider Issuer**,
|
||||
and **Certificate** to **X.509 Certificate** from step 3. Once you've done that, press **Update** to complete the required configuration.
|
||||
|
||||
<Note>
|
||||
If you're self-hosting Infisical, then you will want to replace
|
||||
`https://app.infisical.com` with your own domain.
|
||||
</Note>
|
||||

|
||||
</Step>
|
||||
<Step title="Assign users in Okta to the application">
|
||||
Back in Okta, navigate to the **Assignments** tab and select **Assign**. You can assign access to the application on a user-by-user basis using the Assign to People option, or in-bulk using the Assign to Groups option.
|
||||
|
||||
6. Also on the Configure SAML screen, configure the **Attribute Statements** to map:
|
||||

|
||||
|
||||
- `id -> user.id`,
|
||||
- `email -> user.email`,
|
||||
- `firstName -> user.firstName`
|
||||
- `lastName -> user.lastName`
|
||||
At this point, you have configured everything you need within the context of the Okta Admin Portal.
|
||||
</Step>
|
||||
<Step title="Enable SAML SSO in Infisical">
|
||||
Enabling SAML SSO enforces all members in your organization to only be able to log into Infisical via Okta.
|
||||
|
||||

|
||||
|
||||
Once configured, select **Next** to proceed to the Feedback screen and select **Finish**.
|
||||
|
||||
7. Get IdP values
|
||||
|
||||
Once your application is created, select the **Sign On** tab for the app and select the **View Setup Instructions** button located on the right side of the screen:
|
||||
|
||||

|
||||
|
||||
Copy the **Identity Provider Single Sign-On URL**, the **Identity Provider Issuer**, and the **X.509 Certificate** to use when finishing configuring Okta SAML in Infisical.
|
||||
|
||||

|
||||
|
||||
Back in Infisical, set **Identity Provider Single Sign-On URL**, **Identity Provider Issuer**,
|
||||
and **Certificate** to **X.509 Certificate** from above. Once you've done that, press **Update** to complete the required configuration.
|
||||
|
||||

|
||||
|
||||
8. Finally, navigate to the **Assignments** tab and select **Assign**
|
||||
|
||||
You can assign access to the application on a user-by-user basis using the Assign to People option, or in-bulk using the Assign to Groups option.
|
||||
|
||||

|
||||
|
||||
At this point, you have configured everything you need within the context of the Okta Admin Portal.
|
||||
|
||||
9. Return to Infisical and enable SAML SSO.
|
||||
|
||||
Enabling SAML SSO enforces all members in your organization to only be able to log into Infisical via Okta.
|
||||
|
||||

|
||||

|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
If you're configuring SAML SSO on a self-hosted instance of Infisical, make sure to
|
||||
set the `JWT_PROVIDER_AUTH_SECRET` and `SITE_URL` environment variable for it to work:
|
||||
set the `AUTH_SECRET` and `SITE_URL` environment variable for it to work:
|
||||
|
||||
- `JWT_PROVIDER_AUTH_SECRET`: This is secret key used for signing and verifying JWT. This could be a randomly-generated 256-bit hex string.
|
||||
- `AUTH_SECRET`: A secret key used for signing and verifying JWT. This can be a random 32-byte base64 string generated with `openssl rand -base64 32`.
|
||||
- `SITE_URL`: The URL of your self-hosted instance of Infisical - should be an absolute URL including the protocol (e.g. https://app.infisical.com)
|
||||
</Note>
|
@ -63,7 +63,7 @@ export const SecretApprovalRequest = () => {
|
||||
(prev, curr) => ({ ...prev, [curr._id]: curr }),
|
||||
{}
|
||||
);
|
||||
const myMembershipId = members?.find(({ user }) => user._id === presentUser._id)?._id;
|
||||
const myMembershipId = members?.find(({ user }) => user._id === presentUser?._id)?._id;
|
||||
const isSecretApprovalScreen = Boolean(selectedApproval);
|
||||
|
||||
const handleGoBackSecretRequestDetail = () => {
|
||||
@ -101,7 +101,7 @@ export const SecretApprovalRequest = () => {
|
||||
exit={{ opacity: 0, translateX: 30 }}
|
||||
className="rounded-md text-gray-300"
|
||||
>
|
||||
<div className="p-4 px-8 flex items-center space-x-8 bg-mineshaft-800 rounded-t-md border-t border-x border-mineshaft-600">
|
||||
<div className="flex items-center space-x-8 rounded-t-md border-x border-t border-mineshaft-600 bg-mineshaft-800 p-4 px-8">
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
@ -110,7 +110,7 @@ export const SecretApprovalRequest = () => {
|
||||
if (evt.key === "Enter") setStatusFilter("open");
|
||||
}}
|
||||
className={
|
||||
statusFilter === "close" ? "text-gray-500 hover:text-gray-400 duration-100" : ""
|
||||
statusFilter === "close" ? "text-gray-500 duration-100 hover:text-gray-400" : ""
|
||||
}
|
||||
>
|
||||
<FontAwesomeIcon icon={faCodeBranch} className="mr-2" />
|
||||
@ -118,7 +118,7 @@ export const SecretApprovalRequest = () => {
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
statusFilter === "open" ? "text-gray-500 hover:text-gray-400 duration-100" : ""
|
||||
statusFilter === "open" ? "text-gray-500 duration-100 hover:text-gray-400" : ""
|
||||
}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
@ -130,7 +130,7 @@ export const SecretApprovalRequest = () => {
|
||||
<FontAwesomeIcon icon={faCheck} className="mr-2" />
|
||||
{isSecretApprovalReqCountSuccess && secretApprovalRequestCount.closed} Closed
|
||||
</div>
|
||||
<div className="flex-grow flex justify-end space-x-8">
|
||||
<div className="flex flex-grow justify-end space-x-8">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger>
|
||||
<Button
|
||||
@ -185,7 +185,7 @@ export const SecretApprovalRequest = () => {
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col border-t border-mineshaft-600 bg-mineshaft-800 rounded-b-md border-b border-x border-mineshaft-600">
|
||||
<div className="flex flex-col rounded-b-md border-x border-t border-b border-mineshaft-600 border-mineshaft-600 bg-mineshaft-800">
|
||||
{isRequestListEmpty && (
|
||||
<div className="py-12">
|
||||
<EmptyState title="No more requests pending." />
|
||||
@ -246,9 +246,9 @@ export const SecretApprovalRequest = () => {
|
||||
>
|
||||
<div className="mb-2 flex items-center">
|
||||
<FontAwesomeIcon icon={faCodeBranch} className="mr-2" />
|
||||
<Skeleton className="bg-mineshaft-600 w-1/4" />
|
||||
<Skeleton className="w-1/4 bg-mineshaft-600" />
|
||||
</div>
|
||||
<Skeleton className="bg-mineshaft-600 w-1/2" />
|
||||
<Skeleton className="w-1/2 bg-mineshaft-600" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
@ -22,6 +22,7 @@ type Props = {
|
||||
isMergable?: boolean;
|
||||
status: "close" | "open";
|
||||
approvals: number;
|
||||
canApprove?: boolean;
|
||||
statusChangeByEmail: string;
|
||||
workspaceId: string;
|
||||
};
|
||||
@ -33,7 +34,8 @@ export const SecretApprovalRequestAction = ({
|
||||
isMergable,
|
||||
approvals,
|
||||
statusChangeByEmail,
|
||||
workspaceId
|
||||
workspaceId,
|
||||
canApprove
|
||||
}: Props) => {
|
||||
const { createNotification } = useNotificationContext();
|
||||
const { mutateAsync: performSecretApprovalMerge, isLoading: isMerging } =
|
||||
@ -83,11 +85,11 @@ export const SecretApprovalRequestAction = ({
|
||||
|
||||
if (!hasMerged && status === "open") {
|
||||
return (
|
||||
<div className="flex justify-between items-center w-full">
|
||||
<div className="flex space-x-4 items-start">
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div className="flex items-start space-x-4">
|
||||
<FontAwesomeIcon
|
||||
icon={isMergable ? faSquareCheck : faSquareXmark}
|
||||
className={twMerge("text-2xl pt-1", isMergable ? "text-primary" : "text-red-600")}
|
||||
className={twMerge("pt-1 text-2xl", isMergable ? "text-primary" : "text-red-600")}
|
||||
/>
|
||||
<span className="flex flex-col">
|
||||
{isMergable ? "Good to merge" : "Review required"}
|
||||
@ -98,25 +100,31 @@ export const SecretApprovalRequestAction = ({
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button
|
||||
onClick={() => handleSecretApprovalStatusChange("close")}
|
||||
isLoading={isStatusChanging}
|
||||
variant="outline_bg"
|
||||
colorSchema="secondary"
|
||||
leftIcon={<FontAwesomeIcon icon={faClose} />}
|
||||
>
|
||||
Close request
|
||||
</Button>
|
||||
<Button
|
||||
leftIcon={<FontAwesomeIcon icon={faCheck} />}
|
||||
isDisabled={!isMergable}
|
||||
isLoading={isMerging}
|
||||
onClick={handleSecretApprovalRequestMerge}
|
||||
colorSchema="primary"
|
||||
variant="solid"
|
||||
>
|
||||
Merge
|
||||
</Button>
|
||||
{canApprove ? (
|
||||
<>
|
||||
<Button
|
||||
onClick={() => handleSecretApprovalStatusChange("close")}
|
||||
isLoading={isStatusChanging}
|
||||
variant="outline_bg"
|
||||
colorSchema="secondary"
|
||||
leftIcon={<FontAwesomeIcon icon={faClose} />}
|
||||
>
|
||||
Close request
|
||||
</Button>
|
||||
<Button
|
||||
leftIcon={<FontAwesomeIcon icon={faCheck} />}
|
||||
isDisabled={!isMergable}
|
||||
isLoading={isMerging}
|
||||
onClick={handleSecretApprovalRequestMerge}
|
||||
colorSchema="primary"
|
||||
variant="solid"
|
||||
>
|
||||
Merge
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<div>Only approvers can merge</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -124,9 +132,9 @@ export const SecretApprovalRequestAction = ({
|
||||
|
||||
if (hasMerged && status === "close")
|
||||
return (
|
||||
<div className="flex justify-between items-center w-full">
|
||||
<div className="flex space-x-4 items-start">
|
||||
<FontAwesomeIcon icon={faCheck} className="text-2xl text-primary pt-1" />
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div className="flex items-start space-x-4">
|
||||
<FontAwesomeIcon icon={faCheck} className="pt-1 text-2xl text-primary" />
|
||||
<span className="flex flex-col">
|
||||
Change request merged
|
||||
<span className="inline-block text-xs text-bunker-200">
|
||||
@ -138,9 +146,9 @@ export const SecretApprovalRequestAction = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex justify-between items-center w-full">
|
||||
<div className="flex space-x-4 items-start">
|
||||
<FontAwesomeIcon icon={faUserLock} className="text-2xl text-primary pt-1" />
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div className="flex items-start space-x-4">
|
||||
<FontAwesomeIcon icon={faUserLock} className="pt-1 text-2xl text-primary" />
|
||||
<span className="flex flex-col">
|
||||
Change request has been closed
|
||||
<span className="inline-block text-xs text-bunker-200">
|
||||
|
@ -108,6 +108,7 @@ export const SecretApprovalRequestChanges = ({
|
||||
({ user: membershipUser }) => membershipUser.email === user.email
|
||||
);
|
||||
const myMembershipId = myMembership?._id || "";
|
||||
const canApprove = secretApprovalRequestDetails?.policy?.approvers?.includes(myMembershipId);
|
||||
const reviewedMembers = secretApprovalRequestDetails?.reviewers?.reduce<
|
||||
Record<string, ApprovalStatus>
|
||||
>(
|
||||
@ -164,30 +165,30 @@ export const SecretApprovalRequestChanges = ({
|
||||
return (
|
||||
<div className="flex space-x-6">
|
||||
<div className="flex-grow">
|
||||
<div className="flex items-center space-x-4 pt-2 pb-6 sticky top-0 z-20 bg-bunker-800">
|
||||
<div className="sticky top-0 z-20 flex items-center space-x-4 bg-bunker-800 pt-2 pb-6">
|
||||
<IconButton variant="outline_bg" ariaLabel="go-back" onClick={onGoBack}>
|
||||
<FontAwesomeIcon icon={faArrowLeft} />
|
||||
</IconButton>
|
||||
<div className="bg-red-600 text-white flex items-center space-x-2 px-4 py-2 rounded-3xl">
|
||||
<div className="flex items-center space-x-2 rounded-3xl bg-red-600 px-4 py-2 text-white">
|
||||
<FontAwesomeIcon icon={faCodeBranch} size="sm" />
|
||||
<span>{secretApprovalRequestDetails.status}</span>
|
||||
</div>
|
||||
<div className="flex flex-col flex-grow">
|
||||
<div className="text-lg mb-1">
|
||||
<div className="flex flex-grow flex-col">
|
||||
<div className="mb-1 text-lg">
|
||||
{generateCommitText(secretApprovalRequestDetails.commits)}
|
||||
</div>
|
||||
<div className="text-sm text-bunker-300 flex items-center">
|
||||
<div className="flex items-center text-sm text-bunker-300">
|
||||
{committer?.user?.firstName}
|
||||
{committer?.user?.lastName} ({committer?.user?.email}) wants to change{" "}
|
||||
{secretApprovalRequestDetails.commits.length} secret values in
|
||||
<span className="text-primary-300 bg-primary-600/60 px-1 mx-1 rounded">
|
||||
<span className="mx-1 rounded bg-primary-600/60 px-1 text-primary-300">
|
||||
{secretApprovalRequestDetails.environment}
|
||||
</span>
|
||||
<div className="flex items-center border border-mineshaft-500 pl-1 pr-2 rounded w-min">
|
||||
<div className="flex w-min items-center rounded border border-mineshaft-500 pl-1 pr-2">
|
||||
<div className="border-r border-mineshaft-500 pr-1">
|
||||
<FontAwesomeIcon icon={faFolder} className="text-primary" size="sm" />
|
||||
</div>
|
||||
<div className="text-sm pl-2 pb-0.5">{secretApprovalRequestDetails.secretPath}</div>
|
||||
<div className="pl-2 pb-0.5 text-sm">{secretApprovalRequestDetails.secretPath}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -198,7 +199,7 @@ export const SecretApprovalRequestChanges = ({
|
||||
leftIcon={hasApproved && <FontAwesomeIcon icon={faCheck} />}
|
||||
onClick={() => handleSecretApprovalStatusUpdate(ApprovalStatus.APPROVED)}
|
||||
isLoading={isApproving}
|
||||
isDisabled={isApproving || hasApproved}
|
||||
isDisabled={isApproving || hasApproved || !canApprove}
|
||||
>
|
||||
{hasApproved ? "Approved" : "Approve"}
|
||||
</Button>
|
||||
@ -208,7 +209,7 @@ export const SecretApprovalRequestChanges = ({
|
||||
leftIcon={hasRejected && <FontAwesomeIcon icon={faCheck} />}
|
||||
onClick={() => handleSecretApprovalStatusUpdate(ApprovalStatus.REJECTED)}
|
||||
isLoading={isRejecting}
|
||||
isDisabled={isRejecting || hasRejected}
|
||||
isDisabled={isRejecting || hasRejected || !canApprove}
|
||||
>
|
||||
{hasRejected ? "Rejected" : "Reject"}
|
||||
</Button>
|
||||
@ -230,8 +231,9 @@ export const SecretApprovalRequestChanges = ({
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center px-5 py-6 rounded-lg space-x-6 bg-mineshaft-800 mt-8">
|
||||
<div className="mt-8 flex items-center space-x-6 rounded-lg bg-mineshaft-800 px-5 py-6">
|
||||
<SecretApprovalRequestAction
|
||||
canApprove={canApprove}
|
||||
approvalRequestId={secretApprovalRequestDetails._id}
|
||||
hasMerged={hasMerged}
|
||||
approvals={secretApprovalRequestDetails.policy.approvals || 0}
|
||||
@ -244,7 +246,7 @@ export const SecretApprovalRequestChanges = ({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-1/5 pt-4 sticky top-0" style={{ minWidth: "240px" }}>
|
||||
<div className="sticky top-0 w-1/5 pt-4" style={{ minWidth: "240px" }}>
|
||||
<div className="text-sm text-bunker-300">Reviewers</div>
|
||||
<div className="mt-2 flex flex-col space-y-2 text-sm">
|
||||
{secretApprovalRequestDetails?.policy?.approvers.map((requiredApproverId) => {
|
||||
@ -252,7 +254,7 @@ export const SecretApprovalRequestChanges = ({
|
||||
const status = reviewedMembers?.[requiredApproverId];
|
||||
return (
|
||||
<div
|
||||
className="flex items-center space-x-2 flex-nowrap bg-mineshaft-800 px-2 py-1 rounded"
|
||||
className="flex flex-nowrap items-center space-x-2 rounded bg-mineshaft-800 px-2 py-1"
|
||||
key={`required-approver-${requiredApproverId}`}
|
||||
>
|
||||
<div className="flex-grow text-sm">
|
||||
@ -278,7 +280,7 @@ export const SecretApprovalRequestChanges = ({
|
||||
const status = reviewedMembers?.[reviewer.status];
|
||||
return (
|
||||
<div
|
||||
className="flex items-center space-x-2 flex-nowrap bg-mineshaft-800 px-2 py-1 rounded"
|
||||
className="flex flex-nowrap items-center space-x-2 rounded bg-mineshaft-800 px-2 py-1"
|
||||
key={`required-approver-${reviewer.member}`}
|
||||
>
|
||||
<div className="flex-grow text-sm">
|
||||
|
Reference in New Issue
Block a user