Files
spacedrive/interface/app/$libraryId/KeyManager/NotSetup.tsx
jake da58ba916f [ENG-490] Add support for late key manager setup (#740)
* support for late key manager setup and remove password from onboarding

* mobile

* delete master-password.tsx

* remove secure temp keystore

* remove more km_config artifacts

* fix builds

* Fix most of the UI, there still some minor bugs

* Workaround portalled closing Popovers

* Restore search in core/src/api/mod.rs

* Fix Password eye icon closing Popover on click

* Fix keymanager setup submit button spinner not centered
 - Fix keymanager setup missing logic for disabling form
 - Adjust keymanager tab roundness to match app style

* Restore .gitignore

* Restore .prettierignore

* fixerino tests

---------

Co-authored-by: Utku Bakir <74243531+utkubakir@users.noreply.github.com>
Co-authored-by: Vítor Vasconcellos <vasconcellos.dev@gmail.com>
2023-04-22 09:10:21 +00:00

138 lines
3.8 KiB
TypeScript

import clsx from 'clsx';
import { CaretRight, Spinner } from 'phosphor-react';
import { useState } from 'react';
import {
HASHING_ALGOS,
hashingAlgoSlugSchema,
useLibraryMutation,
useLibraryQuery
} from '@sd/client';
import { Button, SelectOption, forms } from '@sd/ui';
import { Form } from '~/../packages/ui/src/forms';
const { z, useZodForm, PasswordInput, Select } = forms;
const schema = z
.object({
password: z.string(),
passwordValidate: z.string(),
algorithm: z.enum(['XChaCha20Poly1305', 'Aes256Gcm']),
hashingAlgorithm: hashingAlgoSlugSchema
})
.superRefine((data, ctx) => {
if (!data.password || !data.passwordValidate) {
ctx.addIssue({
code: 'custom',
path: ['password', 'passwordValidate'],
message: 'Password is required'
});
}
if (data.password && data.password !== data.passwordValidate) {
ctx.addIssue({
code: 'custom',
path: ['passwordValidate'],
message: 'Passwords do not match'
});
}
});
export default () => {
const isSetup = useLibraryQuery(['keys.isSetup']);
const setupKeyManager = useLibraryMutation('keys.setup');
const [showAdvancedOptions, setShowAdvancedOptions] = useState(false);
const form = useZodForm({
schema: schema,
defaultValues: {
password: '',
passwordValidate: '',
algorithm: 'XChaCha20Poly1305',
hashingAlgorithm: 'Argon2id-s'
}
});
const onSubmit = form.handleSubmit((data) =>
setupKeyManager
.mutateAsync({
password: data.password,
algorithm: data.algorithm,
hashing_algorithm: HASHING_ALGOS[data.hashingAlgorithm]
})
.then(() => isSetup.refetch())
);
const isSettingUp = setupKeyManager.isLoading || form.formState.isSubmitting;
return (
<Form form={form} onSubmit={onSubmit} className="w-[350px] p-4">
<div className="space-y-4">
<PasswordInput {...form.register('password')} label="Password" showStrength />
<PasswordInput
{...form.register('passwordValidate', {
onChange: () => form.trigger('passwordValidate')
})}
label="Confirm password"
/>
<div className="rounded-md border border-app-line bg-app-overlay">
<Button
variant="bare"
className={clsx(
'flex w-full border-none !p-3',
showAdvancedOptions && 'rounded-b-none'
)}
onClick={() => setShowAdvancedOptions(!showAdvancedOptions)}
>
Advanced Settings
<CaretRight
weight="bold"
className={clsx('ml-1 transition', showAdvancedOptions && 'rotate-90')}
/>
</Button>
{showAdvancedOptions && (
<div className="space-y-4 p-3 pt-0">
<div className="h-px bg-app-line" />
<Select name="algorithm" label="Algorithm" size="lg" className="!mt-3">
<SelectOption value="XChaCha20Poly1305">
XChaCha20-Poly1305
</SelectOption>
<SelectOption value="Aes256Gcm">AES-256-GCM</SelectOption>
</Select>
<Select name="hashingAlgorithm" label="Hashing Algorithm" size="lg">
<SelectOption value="Argon2id-s">Argon2id (standard)</SelectOption>
<SelectOption value="Argon2id-h">Argon2id (hardened)</SelectOption>
<SelectOption value="Argon2id-p">Argon2id (paranoid)</SelectOption>
<SelectOption value="BalloonBlake3-s">
BLAKE3-Balloon (standard)
</SelectOption>
<SelectOption value="BalloonBlake3-h">
BLAKE3-Balloon (hardened)
</SelectOption>
<SelectOption value="BalloonBlake3-p">
BLAKE3-Balloon (paranoid)
</SelectOption>
</Select>
</div>
)}
</div>
<Button
type="submit"
variant="accent"
disabled={isSettingUp || !form.formState.isValid}
className="w-full"
>
{isSettingUp ? (
<Spinner className="mx-auto h-6 w-6 animate-spin fill-white text-white text-opacity-40" />
) : (
'Set up'
)}
</Button>
</div>
</Form>
);
};