mirror of
https://github.com/its-a-feature/Mythic
synced 2026-06-08 14:55:38 +00:00
apitoken create updates
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import {Box, Checkbox, Chip, Divider, FormControlLabel, InputAdornment, TextField, Typography} from '@mui/material';
|
||||
import {Box, Checkbox, Chip, InputAdornment, TextField, Typography} from '@mui/material';
|
||||
import Button from '@mui/material/Button';
|
||||
import DialogContent from '@mui/material/DialogContent';
|
||||
import DialogTitle from '@mui/material/DialogTitle';
|
||||
@@ -247,13 +247,20 @@ export function SettingsAPITokenDialog(props) {
|
||||
);
|
||||
});
|
||||
}, [filter, groupedScopes]);
|
||||
const visibleScopeCount = React.useMemo(() => {
|
||||
return visibleResources.reduce((prev, resource) => prev + groupedScopes[resource].length, 0);
|
||||
}, [groupedScopes, visibleResources]);
|
||||
const scopeLoadFailed = scopeQueryError !== undefined || scopeData?.apiTokenScopeDefinitions?.status === "error";
|
||||
const scopesUnavailable = scopeLoading || scopeLoadFailed;
|
||||
const selectedScopesLabel = selectedScopes.includes("*") ? "Full access selected" : `${selectedScopes.length} selected`;
|
||||
const fullAccessDisabled = !grantableWildcards.includes("*");
|
||||
|
||||
const onUsernameChange = (name, value, error) => {
|
||||
setName(value);
|
||||
}
|
||||
|
||||
const onAccept = () =>{
|
||||
props.onAccept(name, selectedScopes);
|
||||
props.onAccept(name.trim(), selectedScopes);
|
||||
}
|
||||
const onFilterChange = (event) => {
|
||||
setFilter(event.target.value);
|
||||
@@ -295,12 +302,18 @@ export function SettingsAPITokenDialog(props) {
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<DialogTitle id="form-dialog-title">{props.title}</DialogTitle>
|
||||
<DialogTitle id="form-dialog-title">
|
||||
{props.title}
|
||||
</DialogTitle>
|
||||
<DialogContent dividers={true} >
|
||||
<MythicDialogBody>
|
||||
<MythicDialogSection title="Token Details">
|
||||
<MythicFormGrid minWidth="18rem">
|
||||
<MythicFormField label="Token Name" required>
|
||||
<MythicFormField
|
||||
label="Token Name"
|
||||
description="Use a short name that describes where this token will be used."
|
||||
required
|
||||
>
|
||||
<MythicTextField
|
||||
autoFocus
|
||||
placeholder={props.name}
|
||||
@@ -320,108 +333,126 @@ export function SettingsAPITokenDialog(props) {
|
||||
description="Tokens with no scopes are created with no API access. Write scopes include read access for the same resource."
|
||||
actions={
|
||||
<>
|
||||
<Chip size="small" label={`${selectedScopes.length} selected`} />
|
||||
<Button size="small" onClick={selectVisibleScopes}>
|
||||
<Chip className="mythic-api-token-scope-count" size="small" label={`${visibleScopeCount} visible`} />
|
||||
<Chip className="mythic-api-token-scope-count" size="small" label={selectedScopesLabel} />
|
||||
<Button disabled={scopesUnavailable || visibleScopeCount === 0 || scopeIsSelected("*")} size="small" onClick={selectVisibleScopes}>
|
||||
Select Visible
|
||||
</Button>
|
||||
<Button size="small" onClick={clearScopes}>
|
||||
<Button disabled={selectedScopes.length === 0} size="small" onClick={clearScopes}>
|
||||
Clear
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<TextField
|
||||
className="mythic-api-token-scope-search"
|
||||
size="small"
|
||||
fullWidth
|
||||
value={filter}
|
||||
onChange={onFilterChange}
|
||||
placeholder="Search scopes"
|
||||
disabled={scopeLoading || scopeQueryError !== undefined || scopeData?.apiTokenScopeDefinitions?.status === "error"}
|
||||
disabled={scopesUnavailable}
|
||||
InputProps={{startAdornment: <InputAdornment position="start"><SearchIcon fontSize="small" /></InputAdornment>}}
|
||||
sx={{mb: 1}}
|
||||
/>
|
||||
<Box sx={{border: theme => `1px solid ${theme.palette.divider}`, borderRadius: 1, maxHeight: "45vh", overflowY: "auto"}}>
|
||||
{(scopeLoading || scopeQueryError !== undefined || scopeData?.apiTokenScopeDefinitions?.status === "error") &&
|
||||
<Box sx={{p: 1.25}}>
|
||||
<Typography variant="body2" color={scopeLoading ? "text.secondary" : "error"}>
|
||||
<Box className="mythic-api-token-scope-library">
|
||||
{scopesUnavailable &&
|
||||
<Box className={`mythic-api-token-scope-state${scopeLoadFailed ? " mythic-api-token-scope-state-error" : ""}`}>
|
||||
<Typography variant="body2">
|
||||
{scopeLoading ? "Loading scopes..." : (scopeQueryError?.message || scopeData?.apiTokenScopeDefinitions?.error || "Failed to load scopes")}
|
||||
</Typography>
|
||||
</Box>
|
||||
}
|
||||
{!scopeLoading && scopeQueryError === undefined && scopeData?.apiTokenScopeDefinitions?.status !== "error" &&
|
||||
{!scopesUnavailable &&
|
||||
<>
|
||||
<Box sx={{p: 1.25}}>
|
||||
<FormControlLabel
|
||||
control={<Checkbox
|
||||
<Box
|
||||
className={`mythic-api-token-scope-card mythic-api-token-scope-card-full${scopeIsSelected("*") ? " mythic-api-token-scope-card-selected" : ""}${fullAccessDisabled ? " mythic-api-token-scope-card-disabled" : ""}`}
|
||||
component="label"
|
||||
>
|
||||
<Checkbox
|
||||
disabled={!grantableWildcards.includes("*")}
|
||||
checked={scopeIsSelected("*")}
|
||||
onChange={() => toggleScope("*")}
|
||||
/>}
|
||||
label={
|
||||
<Box>
|
||||
<Typography variant="body2">Full access (*)</Typography>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
Grants every current and future API scope available to this operator.
|
||||
</Typography>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<Box className="mythic-api-token-scope-card-copy">
|
||||
<Typography className="mythic-api-token-scope-card-title">Full access (*)</Typography>
|
||||
<Typography className="mythic-api-token-scope-card-description">
|
||||
Grants every current and future API scope available to this operator.
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
<Divider />
|
||||
{visibleResources.length === 0 &&
|
||||
<Box className="mythic-api-token-scope-state">
|
||||
<Typography variant="body2">No scopes match your search.</Typography>
|
||||
</Box>
|
||||
}
|
||||
{visibleResources.map(resource => {
|
||||
const resourceWildcard = `${resource}.*`;
|
||||
const canGrantResourceWildcard = grantableWildcards.includes(resourceWildcard);
|
||||
const resourceScopes = groupedScopes[resource].sort((a, b) => a.access.localeCompare(b.access));
|
||||
const resourceScopes = [...groupedScopes[resource]].sort((a, b) => (a.access || "").localeCompare(b.access || ""));
|
||||
const resourceWildcardSelected = scopeIsSelected("*") || scopeIsSelected(resourceWildcard);
|
||||
return (
|
||||
<Box key={resource} sx={{p: 1.25, borderBottom: theme => `1px solid ${theme.palette.divider}`}}>
|
||||
<Box sx={{display: "flex", alignItems: "center", gap: 1, mb: 0.5}}>
|
||||
<Typography variant="subtitle2" sx={{textTransform: "capitalize", flexGrow: 1}}>
|
||||
{resource.split("_").join(" ")}
|
||||
</Typography>
|
||||
<FormControlLabel
|
||||
sx={{mr: 0}}
|
||||
control={<Checkbox
|
||||
<Box className="mythic-api-token-resource-card" key={resource}>
|
||||
<Box className="mythic-api-token-resource-header">
|
||||
<Box sx={{minWidth: 0}}>
|
||||
<Typography className="mythic-api-token-resource-title">
|
||||
{resource.split("_").join(" ")}
|
||||
</Typography>
|
||||
<Typography className="mythic-api-token-resource-subtitle">
|
||||
{resourceScopes.length === 1 ? "1 available scope" : `${resourceScopes.length} available scopes`}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
className={`mythic-api-token-resource-wildcard${resourceWildcardSelected ? " mythic-api-token-resource-wildcard-selected" : ""}${!canGrantResourceWildcard ? " mythic-api-token-resource-wildcard-disabled" : ""}`}
|
||||
component="label"
|
||||
>
|
||||
<Checkbox
|
||||
size="small"
|
||||
disabled={scopeIsSelected("*") || !canGrantResourceWildcard}
|
||||
checked={scopeIsSelected(resourceWildcard)}
|
||||
checked={resourceWildcardSelected}
|
||||
onChange={() => toggleScope(resourceWildcard)}
|
||||
/>}
|
||||
label={<Typography variant="body2">{resourceWildcard}</Typography>}
|
||||
/>
|
||||
/>
|
||||
<span>{resourceWildcard}</span>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box sx={{display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(260px, 1fr))", gap: 1}}>
|
||||
{resourceScopes.map(scope => (
|
||||
<Box className="mythic-api-token-scope-grid">
|
||||
{resourceScopes.map(scope => {
|
||||
const includedByWildcard = scopeIsSelected("*") || scopeIsSelected(resourceWildcard);
|
||||
const scopeSelected = scopeIsSelected(scope.name) || includedByWildcard;
|
||||
return (
|
||||
<Box
|
||||
className={`mythic-api-token-scope-card${scopeSelected ? " mythic-api-token-scope-card-selected" : ""}${includedByWildcard ? " mythic-api-token-scope-card-inherited" : ""}`}
|
||||
component="label"
|
||||
key={scope.name}
|
||||
sx={{
|
||||
border: theme => `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: 1,
|
||||
px: 1,
|
||||
py: 0.5,
|
||||
}}
|
||||
>
|
||||
<FormControlLabel
|
||||
sx={{alignItems: "flex-start", mr: 0}}
|
||||
control={<Checkbox
|
||||
<Checkbox
|
||||
size="small"
|
||||
disabled={scopeIsSelected("*") || scopeIsSelected(resourceWildcard)}
|
||||
checked={scopeIsSelected(scope.name) || scopeIsSelected("*") || scopeIsSelected(resourceWildcard)}
|
||||
disabled={includedByWildcard}
|
||||
checked={scopeSelected}
|
||||
onChange={() => toggleScope(scope.name)}
|
||||
/>}
|
||||
label={
|
||||
<Box>
|
||||
<Typography variant="body2">{scope.display_name || scope.name}</Typography>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
{scope.name}
|
||||
</Typography>
|
||||
<Typography variant="caption" color="text.secondary" sx={{display: "block"}}>
|
||||
{scope.description}
|
||||
</Typography>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<Box className="mythic-api-token-scope-card-copy">
|
||||
<Box className="mythic-api-token-scope-card-title-row">
|
||||
<Typography className="mythic-api-token-scope-card-title">{scope.display_name || scope.name}</Typography>
|
||||
<Chip
|
||||
className={`mythic-api-token-access-chip mythic-api-token-access-chip-${scope.access || "unknown"}`}
|
||||
label={scope.access || "scope"}
|
||||
size="small"
|
||||
/>
|
||||
</Box>
|
||||
<Typography className="mythic-api-token-scope-name">
|
||||
{scope.name}
|
||||
</Typography>
|
||||
<Typography className="mythic-api-token-scope-card-description">
|
||||
{scope.description}
|
||||
</Typography>
|
||||
{scope.includes?.length > 0 &&
|
||||
<Typography className="mythic-api-token-scope-includes">
|
||||
Includes {scope.includes.join(", ")}
|
||||
</Typography>
|
||||
}
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
)})}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
@@ -436,7 +467,7 @@ export function SettingsAPITokenDialog(props) {
|
||||
<MythicDialogButton onClick={props.handleClose}>
|
||||
Cancel
|
||||
</MythicDialogButton>
|
||||
<MythicDialogButton intent="primary" onClick={onAccept}>
|
||||
<MythicDialogButton disabled={name.trim() === ""} intent="primary" onClick={onAccept}>
|
||||
{"Create New"}
|
||||
</MythicDialogButton>
|
||||
</MythicDialogFooter>
|
||||
|
||||
@@ -45,6 +45,7 @@ import {
|
||||
MythicDialogBody,
|
||||
MythicDialogButton,
|
||||
MythicDialogFooter,
|
||||
MythicDialogSection,
|
||||
MythicFormNote
|
||||
} from "../../MythicComponents/MythicDialogLayout";
|
||||
|
||||
@@ -467,20 +468,26 @@ const APITokenValueDialog = ({tokenValue, onClose}) => {
|
||||
<DialogTitle id="form-dialog-title">Copy API Token</DialogTitle>
|
||||
<DialogContent dividers={true}>
|
||||
<MythicDialogBody>
|
||||
<MythicFormNote>
|
||||
<MythicFormNote className="mythic-api-token-copy-warning">
|
||||
This token value is only shown once. Copy it now before closing this dialog.
|
||||
</MythicFormNote>
|
||||
<TextField
|
||||
fullWidth
|
||||
multiline
|
||||
minRows={4}
|
||||
value={tokenValue}
|
||||
InputProps={{readOnly: true}}
|
||||
/>
|
||||
<MythicDialogSection
|
||||
title="Token Value"
|
||||
description="Store this somewhere safe before you close the dialog."
|
||||
>
|
||||
<TextField
|
||||
className="mythic-api-token-value-field"
|
||||
fullWidth
|
||||
multiline
|
||||
minRows={4}
|
||||
value={tokenValue}
|
||||
InputProps={{readOnly: true}}
|
||||
/>
|
||||
</MythicDialogSection>
|
||||
</MythicDialogBody>
|
||||
</DialogContent>
|
||||
<MythicDialogFooter>
|
||||
<MythicDialogButton onClick={onCopyTokenValue} startIcon={<ContentCopyIcon />}>
|
||||
<MythicDialogButton className="mythic-table-row-action-hover-info" onClick={onCopyTokenValue} startIcon={<ContentCopyIcon />}>
|
||||
Copy
|
||||
</MythicDialogButton>
|
||||
<MythicDialogButton intent="primary" onClick={onClose}>
|
||||
|
||||
@@ -1124,6 +1124,228 @@ tspan {
|
||||
.mythic-form-switch-control {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.mythic-api-token-scope-count {
|
||||
background-color: ${(props) => props.theme.palette.mode === "dark" ? alpha(props.theme.palette.common.white, 0.06) : alpha(props.theme.palette.common.black, 0.035)} !important;
|
||||
border: 1px solid ${(props) => props.theme.table?.borderSoft || props.theme.borderColor} !important;
|
||||
color: ${(props) => props.theme.palette.text.primary} !important;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 750;
|
||||
}
|
||||
.mythic-api-token-scope-search {
|
||||
margin-bottom: 0.65rem !important;
|
||||
}
|
||||
.mythic-api-token-scope-search .MuiInputBase-root {
|
||||
background-color: ${(props) => props.theme.surfaces?.raised || props.theme.palette.background.paper};
|
||||
}
|
||||
.mythic-api-token-scope-library {
|
||||
background-color: ${(props) => props.theme.palette.mode === "dark" ? "rgba(255,255,255,0.025)" : "rgba(0,0,0,0.014)"};
|
||||
border: 1px solid ${(props) => props.theme.table?.borderSoft || props.theme.borderColor};
|
||||
border-radius: ${(props) => props.theme.shape.borderRadius}px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.65rem;
|
||||
max-height: 48vh;
|
||||
min-height: 14rem;
|
||||
overflow: auto;
|
||||
padding: 0.65rem;
|
||||
}
|
||||
.mythic-api-token-scope-state {
|
||||
align-items: center;
|
||||
background-color: ${(props) => props.theme.surfaces?.raised || props.theme.palette.background.paper};
|
||||
border: 1px solid ${(props) => props.theme.table?.borderSoft || props.theme.borderColor};
|
||||
border-radius: ${(props) => props.theme.shape.borderRadius}px;
|
||||
color: ${(props) => props.theme.palette.text.secondary};
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-height: 7rem;
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
.mythic-api-token-scope-state-error {
|
||||
background-color: ${(props) => alpha(props.theme.palette.error.main, props.theme.palette.mode === "dark" ? 0.14 : 0.08)};
|
||||
border-color: ${(props) => alpha(props.theme.palette.error.main, props.theme.palette.mode === "dark" ? 0.5 : 0.32)};
|
||||
color: ${(props) => props.theme.palette.error.main};
|
||||
}
|
||||
.mythic-api-token-resource-card {
|
||||
background-color: ${(props) => props.theme.surfaces?.raised || props.theme.palette.background.paper};
|
||||
border: 1px solid ${(props) => props.theme.table?.borderSoft || props.theme.borderColor};
|
||||
border-radius: ${(props) => props.theme.shape.borderRadius}px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.65rem;
|
||||
min-width: 0;
|
||||
padding: 0.75rem;
|
||||
}
|
||||
.mythic-api-token-resource-header {
|
||||
align-items: flex-start;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.75rem;
|
||||
justify-content: space-between;
|
||||
min-width: 0;
|
||||
}
|
||||
.mythic-api-token-resource-title {
|
||||
color: ${(props) => props.theme.palette.text.primary};
|
||||
font-size: 0.9rem;
|
||||
font-weight: 800;
|
||||
line-height: 1.2;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
.mythic-api-token-resource-subtitle {
|
||||
color: ${(props) => props.theme.palette.text.secondary};
|
||||
font-size: 0.74rem;
|
||||
line-height: 1.35;
|
||||
margin-top: 0.15rem;
|
||||
}
|
||||
.mythic-api-token-resource-wildcard {
|
||||
align-items: center;
|
||||
background-color: ${(props) => props.theme.palette.mode === "dark" ? "rgba(255,255,255,0.045)" : "rgba(0,0,0,0.03)"};
|
||||
border: 1px solid ${(props) => props.theme.table?.borderSoft || props.theme.borderColor};
|
||||
border-radius: ${(props) => props.theme.shape.borderRadius}px;
|
||||
color: ${(props) => props.theme.palette.text.secondary};
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
flex: 0 0 auto;
|
||||
font-size: 0.76rem;
|
||||
font-weight: 750;
|
||||
gap: 0.25rem;
|
||||
min-height: 32px;
|
||||
padding: 0.1rem 0.55rem 0.1rem 0.2rem;
|
||||
}
|
||||
.mythic-api-token-resource-wildcard-selected {
|
||||
background-color: ${(props) => alpha(props.theme.palette.primary.main, props.theme.palette.mode === "dark" ? 0.2 : 0.1)};
|
||||
border-color: ${(props) => alpha(props.theme.palette.primary.main, props.theme.palette.mode === "dark" ? 0.58 : 0.38)};
|
||||
color: ${(props) => props.theme.palette.primary.main};
|
||||
}
|
||||
.mythic-api-token-resource-wildcard-disabled {
|
||||
cursor: default;
|
||||
opacity: 0.68;
|
||||
}
|
||||
.mythic-api-token-resource-wildcard .MuiCheckbox-root {
|
||||
padding: 0.1rem;
|
||||
}
|
||||
.mythic-api-token-scope-grid {
|
||||
display: grid;
|
||||
gap: 0.55rem;
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
|
||||
min-width: 0;
|
||||
}
|
||||
.mythic-api-token-scope-card {
|
||||
align-items: flex-start;
|
||||
background-color: ${(props) => props.theme.palette.background.paper};
|
||||
border: 1px solid ${(props) => props.theme.table?.borderSoft || props.theme.borderColor};
|
||||
border-radius: ${(props) => props.theme.shape.borderRadius}px;
|
||||
color: ${(props) => props.theme.palette.text.primary};
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
gap: 0.35rem;
|
||||
min-width: 0;
|
||||
padding: 0.55rem 0.65rem 0.6rem 0.35rem;
|
||||
transition: background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
|
||||
}
|
||||
.mythic-api-token-scope-card:hover {
|
||||
background-color: ${(props) => props.theme.surfaces?.hover || props.theme.palette.action.hover};
|
||||
border-color: ${(props) => props.theme.table?.border || props.theme.borderColor};
|
||||
}
|
||||
.mythic-api-token-scope-card-selected {
|
||||
background-color: ${(props) => alpha(props.theme.palette.primary.main, props.theme.palette.mode === "dark" ? 0.16 : 0.08)};
|
||||
border-color: ${(props) => alpha(props.theme.palette.primary.main, props.theme.palette.mode === "dark" ? 0.58 : 0.38)};
|
||||
}
|
||||
.mythic-api-token-scope-card-inherited {
|
||||
cursor: default;
|
||||
}
|
||||
.mythic-api-token-scope-card-disabled {
|
||||
cursor: default;
|
||||
opacity: 0.68;
|
||||
}
|
||||
.mythic-api-token-scope-card .MuiCheckbox-root {
|
||||
padding: 0.1rem;
|
||||
}
|
||||
.mythic-api-token-scope-card-full {
|
||||
background-color: ${(props) => alpha(props.theme.palette.warning.main, props.theme.palette.mode === "dark" ? 0.12 : 0.07)};
|
||||
border-color: ${(props) => alpha(props.theme.palette.warning.main, props.theme.palette.mode === "dark" ? 0.4 : 0.26)};
|
||||
}
|
||||
.mythic-api-token-scope-card-copy {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.mythic-api-token-scope-card-title-row {
|
||||
align-items: flex-start;
|
||||
display: flex;
|
||||
gap: 0.45rem;
|
||||
justify-content: space-between;
|
||||
min-width: 0;
|
||||
}
|
||||
.mythic-api-token-scope-card-title {
|
||||
color: ${(props) => props.theme.palette.text.primary};
|
||||
font-size: 0.82rem;
|
||||
font-weight: 800;
|
||||
line-height: 1.25;
|
||||
min-width: 0;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.mythic-api-token-scope-name {
|
||||
color: ${(props) => props.theme.palette.text.secondary};
|
||||
font-family: ${(props) => props.theme.typography.fontFamilyMono || "monospace"};
|
||||
font-size: 0.7rem;
|
||||
line-height: 1.35;
|
||||
margin-top: 0.18rem;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.mythic-api-token-scope-card-description,
|
||||
.mythic-api-token-scope-includes {
|
||||
color: ${(props) => props.theme.palette.text.secondary};
|
||||
font-size: 0.74rem;
|
||||
line-height: 1.35;
|
||||
margin-top: 0.25rem;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.mythic-api-token-scope-includes {
|
||||
color: ${(props) => props.theme.palette.info.main};
|
||||
font-weight: 700;
|
||||
}
|
||||
.mythic-api-token-access-chip {
|
||||
border-radius: ${(props) => props.theme.shape.borderRadius}px !important;
|
||||
flex: 0 0 auto;
|
||||
font-size: 0.66rem !important;
|
||||
font-weight: 800 !important;
|
||||
height: 20px !important;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
.mythic-api-token-access-chip-read {
|
||||
background-color: ${(props) => alpha(props.theme.palette.info.main, props.theme.palette.mode === "dark" ? 0.2 : 0.12)} !important;
|
||||
border: 1px solid ${(props) => alpha(props.theme.palette.info.main, props.theme.palette.mode === "dark" ? 0.54 : 0.34)} !important;
|
||||
color: ${(props) => props.theme.palette.info.main} !important;
|
||||
}
|
||||
.mythic-api-token-access-chip-write,
|
||||
.mythic-api-token-access-chip-create,
|
||||
.mythic-api-token-access-chip-update {
|
||||
background-color: ${(props) => alpha(props.theme.palette.success.main, props.theme.palette.mode === "dark" ? 0.2 : 0.12)} !important;
|
||||
border: 1px solid ${(props) => alpha(props.theme.palette.success.main, props.theme.palette.mode === "dark" ? 0.54 : 0.34)} !important;
|
||||
color: ${(props) => props.theme.palette.success.main} !important;
|
||||
}
|
||||
.mythic-api-token-access-chip-delete,
|
||||
.mythic-api-token-access-chip-admin {
|
||||
background-color: ${(props) => alpha(props.theme.palette.error.main, props.theme.palette.mode === "dark" ? 0.2 : 0.12)} !important;
|
||||
border: 1px solid ${(props) => alpha(props.theme.palette.error.main, props.theme.palette.mode === "dark" ? 0.54 : 0.34)} !important;
|
||||
color: ${(props) => props.theme.palette.error.main} !important;
|
||||
}
|
||||
.mythic-api-token-access-chip-unknown {
|
||||
background-color: ${(props) => props.theme.palette.mode === "dark" ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.035)"} !important;
|
||||
border: 1px solid ${(props) => props.theme.table?.borderSoft || props.theme.borderColor} !important;
|
||||
color: ${(props) => props.theme.palette.text.secondary} !important;
|
||||
}
|
||||
.mythic-api-token-copy-warning {
|
||||
background-color: ${(props) => alpha(props.theme.palette.warning.main, props.theme.palette.mode === "dark" ? 0.16 : 0.08)};
|
||||
border-color: ${(props) => alpha(props.theme.palette.warning.main, props.theme.palette.mode === "dark" ? 0.45 : 0.3)};
|
||||
color: ${(props) => props.theme.palette.text.primary};
|
||||
}
|
||||
.mythic-api-token-value-field .MuiInputBase-root {
|
||||
background-color: ${(props) => props.theme.palette.mode === "dark" ? "rgba(0,0,0,0.26)" : "rgba(15,23,42,0.045)"};
|
||||
font-family: ${(props) => props.theme.typography.fontFamilyMono || "monospace"};
|
||||
font-size: 0.78rem;
|
||||
line-height: 1.45;
|
||||
}
|
||||
.mythic-single-task-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user