diff --git a/src/store/account/types.ts b/src/store/account/types.ts index 11436b8..aa0d007 100644 --- a/src/store/account/types.ts +++ b/src/store/account/types.ts @@ -1,11 +1,20 @@ import {ExpiresInValue} from "../../views/ExpiresInInput"; export interface Account { - id: string; - settings: { peer_login_expiration_enabled: boolean, peer_login_expiration: number} + id: string; + settings: { + peer_login_expiration_enabled: boolean; + peer_login_expiration: number; + jwt_groups_enabled: boolean; + groups_propagation_enabled: boolean; + jwt_groups_claim_name: string; + }; } export interface FormAccount extends Account { - peer_login_expiration_enabled: boolean - peer_login_expiration_formatted : ExpiresInValue + peer_login_expiration_enabled: boolean; + jwt_groups_enabled: boolean; + groups_propagation_enabled: boolean; + jwt_groups_claim_name: string; + peer_login_expiration_formatted: ExpiresInValue; } \ No newline at end of file diff --git a/src/views/Settings.tsx b/src/views/Settings.tsx index 733d5eb..419f95a 100644 --- a/src/views/Settings.tsx +++ b/src/views/Settings.tsx @@ -24,6 +24,7 @@ import { MenuProps, } from "antd"; import { filter } from "lodash"; +import { isLocalDev, isNetBirdHosted } from "../utils/common"; import { storeFilterState, getFilterState } from "../utils/filterState"; import { usePageSizeHelpers } from "../utils/pageSize"; import { useGetTokenSilently } from "../utils/token"; @@ -126,6 +127,10 @@ export const Settings = () => { const [formPeerExpirationEnabled, setFormPeerExpirationEnabled] = useState(true); + const [jwtGroupsEnabled, setJwtGroupsEnabled] = useState(true); + const [groupsPropagationEnabled, setGroupsPropagationEnabled] = + useState(true); + const [jwtGroupsClaimName, setJwtGroupsClaimName] = useState(""); const [confirmModal, confirmModalContextHolder] = Modal.useModal(); const { confirm } = Modal; @@ -213,9 +218,15 @@ export const Settings = () => { ), peer_login_expiration_enabled: account.settings.peer_login_expiration_enabled, + jwt_groups_enabled: account.settings.jwt_groups_enabled, + jwt_groups_claim_name: account.settings.jwt_groups_claim_name, + groups_propagation_enabled: account.settings.groups_propagation_enabled, } as FormAccount; setFormAccount(fAccount); setFormPeerExpirationEnabled(fAccount.peer_login_expiration_enabled); + setJwtGroupsEnabled(fAccount.jwt_groups_enabled); + setGroupsPropagationEnabled(fAccount.groups_propagation_enabled); + setJwtGroupsClaimName(fAccount.jwt_groups_claim_name); form.setFieldsValue(fAccount); }, [accounts]); @@ -375,6 +386,11 @@ export const Settings = () => { ), peer_login_expiration_enabled: updatedAccount.data.settings.peer_login_expiration_enabled, + jwt_groups_enabled: updatedAccount.data.settings.jwt_groups_enabled, + jwt_groups_claim_name: + updatedAccount.data.settings.jwt_groups_claim_name, + groups_propagation_enabled: + updatedAccount.data.settings.groups_propagation_enabled, } as FormAccount; setFormAccount(fAccount); } else if (updatedAccount.error) { @@ -406,6 +422,9 @@ export const Settings = () => { confirmSave({ ...values, peer_login_expiration_enabled: formPeerExpirationEnabled, + jwt_groups_enabled: jwtGroupsEnabled, + jwt_groups_claim_name: jwtGroupsClaimName, + groups_propagation_enabled: groupsPropagationEnabled, }); }) .catch((errorInfo) => { @@ -428,6 +447,9 @@ export const Settings = () => { values.peer_login_expiration_formatted ), peer_login_expiration_enabled: values.peer_login_expiration_enabled, + jwt_groups_enabled: jwtGroupsEnabled, + jwt_groups_claim_name: jwtGroupsClaimName, + groups_propagation_enabled: groupsPropagationEnabled, }, } as Account; }; @@ -577,7 +599,296 @@ export const Settings = () => { ]; useEffect(() => {}, [groupsClicked, billingClicked, authClicked]); + const renderSettingForm = () => { + return ( +
+ +
+ {groupsClicked ? "User groups" : "Authentication"} +
+
+ + + +
+ { + setFormPeerExpirationEnabled(checked); + }} + size="small" + checked={formPeerExpirationEnabled} + /> +
+ + + Request periodic re-authentication of peers registered + with SSO + +
+
+
+ +
+ + + + + Time after which every peer added with SSO login will require + re-authentication + + + + + + +
+
+ + + +
+ { + setGroupsPropagationEnabled(checked); + }} + size="small" + checked={groupsPropagationEnabled} + /> +
+ + + Allow group propagation from user’s auto-groups to + peers, sharing membership information + +
+
+
+ +
+ {(isNetBirdHosted() || isLocalDev()) && ( + <> + + + +
+ { + setJwtGroupsEnabled(checked); + }} + size="small" + checked={jwtGroupsEnabled} + /> +
+ + + Extract & sync groups from JWT claims with user’s + auto-groups, auto-creating groups from tokens. + +
+
+
+ +
+ + + + + Specify the JWT claim for extracting group names, e.g., + roles or groups, to add to account groups + + + + + + + { + if (event.code === "Space") event.preventDefault(); + }} + onChange={(e) => { + let val = e.target.value; + var t = val.replace(/ /g, ""); + setJwtGroupsClaimName(t); + }} + /> + + + + + )} +
+ + + Learn more about + + {" "} + login expiration + + + + + + +
+
+ ); + }; return ( <> @@ -597,530 +908,403 @@ export const Settings = () => { {authClicked && ( - -
- -
- Authentication -
- - - -
- { - setFormPeerExpirationEnabled(checked); - }} - size="small" - checked={formPeerExpirationEnabled} - /> -
- - - Request periodic re-authentication of peers - registered with SSO - -
-
-
- -
- - - - - Time after which every peer added with SSO login - will require re-authentication - - - - - - - - - - - Learn more about - - {" "} - login expiration - - - - - - -
-
- + {renderSettingForm()}
)} {groupsClicked && ( - - - -
- - Groups - - - + + {renderSettingForm()} + + + + +
+ - + + - Here is the overview of the groups of your account. - You can delete the unused ones. - - - - - - - - - - - - - - - + + + + +