Skip to content

Commit

Permalink
Merge pull request #292 from HasanMansoor4/auto-capitalization-toggle
Browse files Browse the repository at this point in the history
Auto capitalization toggle for secrets
  • Loading branch information
vmatsiiako authored Feb 8, 2023
2 parents 4570c35 + 231fa61 commit 0d2cadd
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 3 deletions.
40 changes: 39 additions & 1 deletion backend/src/controllers/v2/workspaceController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,4 +467,42 @@ export const deleteWorkspaceMembership = async (req: Request, res: Response) =>
return res.status(200).send({
membership
});
}
}

/**
* Change autoCapitilzation Rule of workspace
* @param req
* @param res
* @returns
*/
export const toggleAutoCapitalization = async (req: Request, res: Response) => {
let workspace;
try {
const { workspaceId } = req.params;
const { autoCapitalization } = req.body;

workspace = await Workspace.findOneAndUpdate(
{
_id: workspaceId
},
{
autoCapitalization
},
{
new: true
}
);
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to change autoCapitalization setting'
});
}

return res.status(200).send({
message: 'Successfully changed autoCapitalization setting',
workspace
});
};

5 changes: 5 additions & 0 deletions backend/src/models/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ export interface IWorkspace {
name: string;
slug: string;
}>;
autoCapitalization: boolean;
}

const workspaceSchema = new Schema<IWorkspace>({
name: {
type: String,
required: true
},
autoCapitalization: {
type: Boolean,
default: true,
},
organization: {
type: Schema.Types.ObjectId,
ref: 'Organization',
Expand Down
15 changes: 15 additions & 0 deletions backend/src/routes/v2/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,19 @@ router.delete( // TODO - rewire dashboard to this route
workspaceController.deleteWorkspaceMembership
);


router.patch(
'/:workspaceId/auto-capitalization',
requireAuth({
acceptedAuthModes: ['jwt']
}),
requireWorkspaceAuth({
acceptedRoles: [ADMIN, MEMBER]
}),
param('workspaceId').exists().trim(),
body('autoCapitalization').exists().trim().notEmpty(),
validateRequest,
workspaceController.toggleAutoCapitalization
);

export default router;
4 changes: 3 additions & 1 deletion frontend/public/locales/en/settings-project.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@
"project-id-description": "To integrate Infisical into your code base and get automatic injection of environmental variables, you should use the following Project ID.",
"project-id-description2": "For more guidance, including code snipets for various languages and frameworks, see ",
"auto-generated": "This is your project's auto-generated unique identifier. It can't be changed.",
"docs": "Infisical Docs"
"docs": "Infisical Docs",
"auto-capitalization": "Auto Capitalization",
"auto-capitalization-description": "According to standards, Infisical will automatically capitalize your keys. If you want to disable this feature, you can do so here."
}
5 changes: 4 additions & 1 deletion frontend/src/components/dashboard/DashboardInputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface DashboardInputFieldProps {
type: 'varName' | 'value' | 'comment';
blurred?: boolean;
isDuplicate?: boolean;
isCapitalized?: boolean;
overrideEnabled?: boolean;
modifyValueOverride?: (value: string | undefined, position: number) => void;
isSideBarOpen?: boolean;
Expand Down Expand Up @@ -41,6 +42,7 @@ const DashboardInputField = ({
value,
blurred,
isDuplicate,
isCapitalized,
overrideEnabled,
modifyValueOverride,
isSideBarOpen
Expand Down Expand Up @@ -69,7 +71,7 @@ const DashboardInputField = ({
}`}
>
<input
onChange={(e) => onChangeHandler(e.target.value.toUpperCase(), position)}
onChange={(e) => onChangeHandler(isCapitalized ? e.target.value.toUpperCase() : e.target.value, position)}
type={type}
value={value}
className={`z-10 peer font-mono ph-no-capture bg-transparent h-full caret-bunker-200 text-sm px-2 w-full min-w-16 outline-none ${
Expand Down Expand Up @@ -230,6 +232,7 @@ function inputPropsAreEqual(prev: DashboardInputFieldProps, next: DashboardInput
prev.type === next.type &&
prev.position === next.position &&
prev.blurred === next.blurred &&
prev.isCapitalized === next.isCapitalized &&
prev.overrideEnabled === next.overrideEnabled &&
prev.isDuplicate === next.isDuplicate &&
prev.isSideBarOpen === next.isSideBarOpen
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/dashboard/KeyPair.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ interface KeyPairProps {
toggleSidebar: (id: string) => void;
sidebarSecretId: string;
isSnapshot: boolean;
isCapitalized: boolean;
deleteRow?: (props: DeleteRowFunctionProps) => void;
tags: Tag[];
togglePITSidebar?: (value: boolean) => void;
Expand Down Expand Up @@ -75,6 +76,7 @@ const KeyPair = ({
isDuplicate,
toggleSidebar,
sidebarSecretId,
isCapitalized,
isSnapshot,
deleteRow,
togglePITSidebar,
Expand All @@ -97,6 +99,7 @@ const KeyPair = ({
<div className='text-bunker-400 text-xs flex items-center justify-center w-14 h-10 cursor-default'>{keyPair.pos + 1}</div>
<div className="flex items-center max-h-16">
<DashboardInputField
isCapitalized = {isCapitalized}
onChangeHandler={modifyKey}
type="varName"
position={keyPair.pos}
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/hooks/api/workspace/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ export {
useGetUserWorkspaces,
useGetWorkspaceById,
useRenameWorkspace,
useToggleAutoCapitalization,
useUpdateWsEnvironment} from './queries';

13 changes: 13 additions & 0 deletions frontend/src/hooks/api/workspace/queries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
DeleteEnvironmentDTO,
DeleteWorkspaceDTO,
RenameWorkspaceDTO,
ToggleAutoCapitalizationDTO,
UpdateEnvironmentDTO,
Workspace
} from './types';
Expand Down Expand Up @@ -51,6 +52,18 @@ export const useRenameWorkspace = () => {
});
};

export const useToggleAutoCapitalization = () => {
const queryClient = useQueryClient();

return useMutation<{}, {}, ToggleAutoCapitalizationDTO>({
mutationFn: ({ workspaceID, state }) =>
apiRequest.patch(`/api/v2/workspace/${workspaceID}/auto-capitalization`, { autoCapitalization: state }),
onSuccess: () => {
queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace);
}
});
};

export const useDeleteWorkspace = () => {
const queryClient = useQueryClient();

Expand Down
2 changes: 2 additions & 0 deletions frontend/src/hooks/api/workspace/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export type Workspace = {
_id: string;
name: string;
organization: string;
autoCapitalization: boolean;
environments: WorkspaceEnv[];
};

Expand All @@ -11,6 +12,7 @@ export type WorkspaceTag = { _id: string; name: string; slug: string };

// mutation dto
export type RenameWorkspaceDTO = { workspaceID: string; newWorkspaceName: string };
export type ToggleAutoCapitalizationDTO = { workspaceID: string; state: boolean };

export type DeleteWorkspaceDTO = { workspaceID: string };

Expand Down
1 change: 1 addition & 0 deletions frontend/src/pages/api/workspace/getWorkspaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ interface Workspace {
__v: number;
_id: string;
name: string;
autoCapitalization: boolean;
organization: string;
environments: Array<{ name: string; slug: string }>;
}
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/pages/dashboard/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export default function Dashboard() {
const [snapshotData, setSnapshotData] = useState<SnapshotProps>();
const [numSnapshots, setNumSnapshots] = useState<number>();
const [saveLoading, setSaveLoading] = useState(false);
const [autoCapitalization, setAutoCapitalization] = useState(false);
const [dropZoneData, setDropZoneData] = useState<SecretDataProps[]>();
const [projectTags, setProjectTags] = useState<Tag[]>([]);

Expand Down Expand Up @@ -224,6 +225,7 @@ export default function Dashboard() {
if (!workspace) {
router.push(`/dashboard/${userWorkspaces?.[0]?._id}`);
}
setAutoCapitalization(workspace?.autoCapitalization ?? true);

const accessibleEnvironments = await getWorkspaceEnvironments({ workspaceId });
setWorkspaceEnvs(accessibleEnvironments || []);
Expand Down Expand Up @@ -874,6 +876,7 @@ export default function Dashboard() {
.filter((row) => !sharedToHide.includes(row.id))
.map((keyPair) => (
<KeyPair
isCapitalized={autoCapitalization}
key={keyPair.id}
keyPair={keyPair}
modifyValue={listenChangeValue}
Expand Down Expand Up @@ -916,6 +919,7 @@ export default function Dashboard() {
)
.map((keyPair) => (
<KeyPair
isCapitalized={autoCapitalization}
key={keyPair.id}
keyPair={keyPair}
modifyValue={listenChangeValue}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/pages/settings/project/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const ProjectSettings = () => {
<title>{t('common:head-title', { title: t('settings-project:title') })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>

<ProjectSettingsPage />
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ import {
useGetUserWsServiceTokens,
useGetWsTags,
useRenameWorkspace,
useToggleAutoCapitalization,
useUpdateWsEnvironment
} from '@app/hooks/api';


import { AutoCapitalizationSection } from './components/AutoCapitalizationSection/AutoCapitalizationSection';

import { SecretTagsSection } from './components/SecretTagsSection';

import {
CopyProjectIDSection,
CreateServiceToken,
Expand All @@ -55,6 +60,8 @@ export const ProjectSettingsPage = () => {
const [isDeleting, setIsDeleting] = useToggle();

const renameWorkspace = useRenameWorkspace();
const toggleAutoCapitalization = useToggleAutoCapitalization();

const deleteWorkspace = useDeleteWorkspace();
// env crud operation
const createWsEnv = useCreateWsEnvironment();
Expand Down Expand Up @@ -93,6 +100,26 @@ export const ProjectSettingsPage = () => {
}
};

const onAutoCapitalizationToggle = async (state: boolean) => {
try {
await toggleAutoCapitalization.mutateAsync({
workspaceID,
state
});
const text = `Successfully ${state ? 'enabled' : 'disabled'} auto capitalization`;
createNotification({
text,
type: 'success'
});
} catch (error) {
console.error(error);
createNotification({
text: 'Failed to update auto capitalization',
type: 'error'
});
}
};

const onDeleteWorkspace = async () => {
setIsDeleting.on();
try {
Expand Down Expand Up @@ -289,6 +316,10 @@ export const ProjectSettingsPage = () => {
workspaceName={currentWorkspace?.name}
onProjectNameChange={onRenameWorkspace}
/>
<AutoCapitalizationSection
workspaceAutoCapitalization={currentWorkspace?.autoCapitalization}
onAutoCapitalizationChange={onAutoCapitalizationToggle}
/>
<CopyProjectIDSection workspaceID={currentWorkspace?._id || ''} />
<EnvironmentSection
environments={currentWorkspace?.environments || []}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useTranslation } from 'react-i18next';

import { Checkbox } from '@app/components/v2';

type Props = {
workspaceAutoCapitalization?: boolean;
onAutoCapitalizationChange: (state: boolean) => Promise<void>;
};

export const AutoCapitalizationSection = ({
workspaceAutoCapitalization,
onAutoCapitalizationChange
}: Props) => {
const { t } = useTranslation();
return (
<form>
<div className="mb-2 flex w-full flex-col items-start rounded-md bg-white/5 px-6 pb-6 pt-2">
<p className="mb-4 mt-2 text-xl font-semibold">
{t('settings-project:auto-capitalization')}
</p>
<Checkbox
className="data-[state=checked]:bg-primary"
id="autoCapitalization"
isChecked={workspaceAutoCapitalization}
onCheckedChange={(state) => {
onAutoCapitalizationChange(state as boolean);
}}
>
{t('settings-project:auto-capitalization-description')}
</Checkbox>
</div>
</form>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AutoCapitalizationSection } from './AutoCapitalizationSection';

0 comments on commit 0d2cadd

Please sign in to comment.