chore: update vaults prefs (#2504)
This commit is contained in:
@@ -5,6 +5,8 @@ import {
|
|||||||
SharedVaultListingInterface,
|
SharedVaultListingInterface,
|
||||||
VaultListingInterface,
|
VaultListingInterface,
|
||||||
KeySystemRootKeyStorageMode,
|
KeySystemRootKeyStorageMode,
|
||||||
|
EmojiString,
|
||||||
|
IconType,
|
||||||
} from '@standardnotes/models'
|
} from '@standardnotes/models'
|
||||||
import { AbstractService } from '../Service/AbstractService'
|
import { AbstractService } from '../Service/AbstractService'
|
||||||
import { SharedVaultServiceEvent, SharedVaultServiceEventPayload } from './SharedVaultServiceEvent'
|
import { SharedVaultServiceEvent, SharedVaultServiceEventPayload } from './SharedVaultServiceEvent'
|
||||||
@@ -14,6 +16,7 @@ export interface SharedVaultServiceInterface
|
|||||||
createSharedVault(dto: {
|
createSharedVault(dto: {
|
||||||
name: string
|
name: string
|
||||||
description?: string
|
description?: string
|
||||||
|
iconString: IconType | EmojiString
|
||||||
userInputtedPassword: string | undefined
|
userInputtedPassword: string | undefined
|
||||||
storagePreference?: KeySystemRootKeyStorageMode
|
storagePreference?: KeySystemRootKeyStorageMode
|
||||||
}): Promise<VaultListingInterface | ClientDisplayableError>
|
}): Promise<VaultListingInterface | ClientDisplayableError>
|
||||||
|
|||||||
@@ -51,12 +51,12 @@ export class VaultUserService extends AbstractService<VaultUserServiceEvent> imp
|
|||||||
return result.getValue()
|
return result.getValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
public isCurrentUserSharedVaultAdmin(sharedVault: SharedVaultListingInterface): boolean {
|
public isCurrentUserSharedVaultOwner(sharedVault: SharedVaultListingInterface): boolean {
|
||||||
return this._isVaultOwner.execute(sharedVault).getValue()
|
return this._isVaultOwner.execute(sharedVault).getValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
async removeUserFromSharedVault(sharedVault: SharedVaultListingInterface, userUuid: string): Promise<Result<void>> {
|
async removeUserFromSharedVault(sharedVault: SharedVaultListingInterface, userUuid: string): Promise<Result<void>> {
|
||||||
if (!this.isCurrentUserSharedVaultAdmin(sharedVault)) {
|
if (!this.isCurrentUserSharedVaultOwner(sharedVault)) {
|
||||||
throw new Error('Only vault admins can remove users')
|
throw new Error('Only vault admins can remove users')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Result } from '@standardnotes/domain-core'
|
|||||||
|
|
||||||
export interface VaultUserServiceInterface extends ApplicationServiceInterface<VaultUserServiceEvent, unknown> {
|
export interface VaultUserServiceInterface extends ApplicationServiceInterface<VaultUserServiceEvent, unknown> {
|
||||||
getSharedVaultUsers(sharedVault: SharedVaultListingInterface): Promise<SharedVaultUserServerHash[] | undefined>
|
getSharedVaultUsers(sharedVault: SharedVaultListingInterface): Promise<SharedVaultUserServerHash[] | undefined>
|
||||||
isCurrentUserSharedVaultAdmin(sharedVault: SharedVaultListingInterface): boolean
|
isCurrentUserSharedVaultOwner(sharedVault: SharedVaultListingInterface): boolean
|
||||||
removeUserFromSharedVault(sharedVault: SharedVaultListingInterface, userUuid: string): Promise<Result<void>>
|
removeUserFromSharedVault(sharedVault: SharedVaultListingInterface, userUuid: string): Promise<Result<void>>
|
||||||
leaveSharedVault(sharedVault: SharedVaultListingInterface): Promise<ClientDisplayableError | void>
|
leaveSharedVault(sharedVault: SharedVaultListingInterface): Promise<ClientDisplayableError | void>
|
||||||
isVaultUserOwner(user: SharedVaultUserServerHash): boolean
|
isVaultUserOwner(user: SharedVaultUserServerHash): boolean
|
||||||
|
|||||||
@@ -37,8 +37,12 @@ const Vaults = () => {
|
|||||||
const [isAddContactModalOpen, setIsAddContactModalOpen] = useState(false)
|
const [isAddContactModalOpen, setIsAddContactModalOpen] = useState(false)
|
||||||
const closeAddContactModal = () => setIsAddContactModalOpen(false)
|
const closeAddContactModal = () => setIsAddContactModalOpen(false)
|
||||||
|
|
||||||
|
const [isCreatingSharedVault, setIsCreatingSharedVault] = useState(false)
|
||||||
const [isVaultModalOpen, setIsVaultModalOpen] = useState(false)
|
const [isVaultModalOpen, setIsVaultModalOpen] = useState(false)
|
||||||
const closeVaultModal = () => setIsVaultModalOpen(false)
|
const closeVaultModal = () => {
|
||||||
|
setIsVaultModalOpen(false)
|
||||||
|
setIsCreatingSharedVault(false)
|
||||||
|
}
|
||||||
|
|
||||||
const vaultService = application.vaults
|
const vaultService = application.vaults
|
||||||
const contactService = application.contacts
|
const contactService = application.contacts
|
||||||
@@ -46,17 +50,20 @@ const Vaults = () => {
|
|||||||
|
|
||||||
const updateVaults = useCallback(async () => {
|
const updateVaults = useCallback(async () => {
|
||||||
const vaults = vaultService.getVaults()
|
const vaults = vaultService.getVaults()
|
||||||
|
const ownedVaults = vaults.filter((vault) => {
|
||||||
|
return !vault.isSharedVaultListing() ? true : application.vaultUsers.isCurrentUserSharedVaultOwner(vault)
|
||||||
|
})
|
||||||
|
|
||||||
if (featuresService.hasMinimumRole(RoleName.NAMES.ProUser)) {
|
if (featuresService.hasMinimumRole(RoleName.NAMES.ProUser)) {
|
||||||
setCanCreateMoreVaults(true)
|
setCanCreateMoreVaults(true)
|
||||||
} else if (featuresService.hasMinimumRole(RoleName.NAMES.PlusUser)) {
|
} else if (featuresService.hasMinimumRole(RoleName.NAMES.PlusUser)) {
|
||||||
setCanCreateMoreVaults(vaults.length < 3)
|
setCanCreateMoreVaults(ownedVaults.length < 3)
|
||||||
} else {
|
} else {
|
||||||
setCanCreateMoreVaults(vaults.length < 1)
|
setCanCreateMoreVaults(ownedVaults.length < 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
setVaults(vaults)
|
setVaults(vaults)
|
||||||
}, [vaultService, featuresService])
|
}, [vaultService, featuresService, application.vaultUsers])
|
||||||
|
|
||||||
const updateInvites = useCallback(async () => {
|
const updateInvites = useCallback(async () => {
|
||||||
setInvites(application.vaultInvites.getCachedPendingInviteRecords())
|
setInvites(application.vaultInvites.getCachedPendingInviteRecords())
|
||||||
@@ -115,6 +122,11 @@ const Vaults = () => {
|
|||||||
setIsVaultModalOpen(true)
|
setIsVaultModalOpen(true)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const createNewSharedVault = useCallback(async () => {
|
||||||
|
setIsCreatingSharedVault(true)
|
||||||
|
setIsVaultModalOpen(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
const createNewContact = useCallback(() => {
|
const createNewContact = useCallback(() => {
|
||||||
setIsAddContactModalOpen(true)
|
setIsAddContactModalOpen(true)
|
||||||
}, [])
|
}, [])
|
||||||
@@ -125,7 +137,11 @@ const Vaults = () => {
|
|||||||
<EditContactModal onCloseDialog={closeAddContactModal} />
|
<EditContactModal onCloseDialog={closeAddContactModal} />
|
||||||
</ModalOverlay>
|
</ModalOverlay>
|
||||||
|
|
||||||
<EditVaultModal isVaultModalOpen={isVaultModalOpen} closeVaultModal={closeVaultModal} />
|
<EditVaultModal
|
||||||
|
isVaultModalOpen={isVaultModalOpen}
|
||||||
|
creatingSharedVault={isCreatingSharedVault}
|
||||||
|
closeVaultModal={closeVaultModal}
|
||||||
|
/>
|
||||||
|
|
||||||
{invites.length > 0 && (
|
{invites.length > 0 && (
|
||||||
<PreferencesGroup>
|
<PreferencesGroup>
|
||||||
@@ -169,8 +185,9 @@ const Vaults = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{canCreateMoreVaults ? (
|
{canCreateMoreVaults ? (
|
||||||
<div className="mt-2.5 flex flex-row">
|
<div className="mt-2.5 flex gap-3">
|
||||||
<Button label="Create New Vault" className="mr-3" onClick={createNewVault} />
|
<Button label="Create Vault" onClick={createNewVault} />
|
||||||
|
<Button label="Create Shared Vault" onClick={createNewSharedVault} />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="mt-3.5">
|
<div className="mt-3.5">
|
||||||
|
|||||||
@@ -28,8 +28,9 @@ import Spinner from '@/Components/Spinner/Spinner'
|
|||||||
|
|
||||||
const EditVaultModalContent: FunctionComponent<{
|
const EditVaultModalContent: FunctionComponent<{
|
||||||
existingVaultUuid?: string
|
existingVaultUuid?: string
|
||||||
|
creatingSharedVault?: boolean
|
||||||
onCloseDialog: () => void
|
onCloseDialog: () => void
|
||||||
}> = ({ onCloseDialog, existingVaultUuid }) => {
|
}> = ({ onCloseDialog, existingVaultUuid, creatingSharedVault }) => {
|
||||||
const application = useApplication()
|
const application = useApplication()
|
||||||
|
|
||||||
const existingVault = useItem<VaultListingInterface>(existingVaultUuid)
|
const existingVault = useItem<VaultListingInterface>(existingVaultUuid)
|
||||||
@@ -65,7 +66,7 @@ const EditVaultModalContent: FunctionComponent<{
|
|||||||
|
|
||||||
if (existingVault.isSharedVaultListing()) {
|
if (existingVault.isSharedVaultListing()) {
|
||||||
setIsAdmin(
|
setIsAdmin(
|
||||||
existingVault.isSharedVaultListing() && application.vaultUsers.isCurrentUserSharedVaultAdmin(existingVault),
|
existingVault.isSharedVaultListing() && application.vaultUsers.isCurrentUserSharedVaultOwner(existingVault),
|
||||||
)
|
)
|
||||||
|
|
||||||
setIsLoadingCollaborationInfo(true)
|
setIsLoadingCollaborationInfo(true)
|
||||||
@@ -160,12 +161,30 @@ const EditVaultModalContent: FunctionComponent<{
|
|||||||
if (!customPassword) {
|
if (!customPassword) {
|
||||||
throw new Error('Custom key is not set')
|
throw new Error('Custom key is not set')
|
||||||
}
|
}
|
||||||
await application.vaults.createUserInputtedPasswordVault({
|
if (creatingSharedVault) {
|
||||||
|
await application.sharedVaults.createSharedVault({
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
iconString: iconString,
|
||||||
|
storagePreference: keyStorageMode,
|
||||||
|
userInputtedPassword: customPassword,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
await application.vaults.createUserInputtedPasswordVault({
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
iconString: iconString,
|
||||||
|
storagePreference: keyStorageMode,
|
||||||
|
userInputtedPassword: customPassword,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (creatingSharedVault) {
|
||||||
|
await application.sharedVaults.createSharedVault({
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
iconString: iconString,
|
iconString: iconString,
|
||||||
storagePreference: keyStorageMode,
|
storagePreference: keyStorageMode,
|
||||||
userInputtedPassword: customPassword,
|
userInputtedPassword: undefined,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
await application.vaults.createRandomizedVault({
|
await application.vaults.createRandomizedVault({
|
||||||
@@ -177,7 +196,9 @@ const EditVaultModalContent: FunctionComponent<{
|
|||||||
|
|
||||||
handleDialogClose()
|
handleDialogClose()
|
||||||
}, [
|
}, [
|
||||||
|
application.sharedVaults,
|
||||||
application.vaults,
|
application.vaults,
|
||||||
|
creatingSharedVault,
|
||||||
customPassword,
|
customPassword,
|
||||||
description,
|
description,
|
||||||
handleDialogClose,
|
handleDialogClose,
|
||||||
@@ -203,7 +224,7 @@ const EditVaultModalContent: FunctionComponent<{
|
|||||||
const modalActions = useMemo(
|
const modalActions = useMemo(
|
||||||
(): ModalAction[] => [
|
(): ModalAction[] => [
|
||||||
{
|
{
|
||||||
label: existingVault ? 'Save Vault' : 'Create Vault',
|
label: existingVault ? 'Save Vault' : creatingSharedVault ? 'Create Shared Vault' : 'Create Vault',
|
||||||
onClick: handleSubmit,
|
onClick: handleSubmit,
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
mobileSlot: 'right',
|
mobileSlot: 'right',
|
||||||
@@ -216,7 +237,7 @@ const EditVaultModalContent: FunctionComponent<{
|
|||||||
mobileSlot: 'left',
|
mobileSlot: 'left',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[existingVault, handleDialogClose, handleSubmit, isSubmitting],
|
[creatingSharedVault, existingVault, handleDialogClose, handleSubmit, isSubmitting],
|
||||||
)
|
)
|
||||||
|
|
||||||
const [shouldShowIconPicker, setShouldShowIconPicker] = useState(false)
|
const [shouldShowIconPicker, setShouldShowIconPicker] = useState(false)
|
||||||
@@ -334,14 +355,20 @@ const EditVaultModal = ({
|
|||||||
isVaultModalOpen,
|
isVaultModalOpen,
|
||||||
closeVaultModal,
|
closeVaultModal,
|
||||||
vault,
|
vault,
|
||||||
|
creatingSharedVault,
|
||||||
}: {
|
}: {
|
||||||
isVaultModalOpen: boolean
|
isVaultModalOpen: boolean
|
||||||
closeVaultModal: () => void
|
closeVaultModal: () => void
|
||||||
vault?: VaultListingInterface
|
vault?: VaultListingInterface
|
||||||
|
creatingSharedVault?: boolean
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<ModalOverlay className="md:max-h-[70vh]" isOpen={isVaultModalOpen} close={closeVaultModal}>
|
<ModalOverlay className="md:max-h-[70vh]" isOpen={isVaultModalOpen} close={closeVaultModal}>
|
||||||
<EditVaultModalContent existingVaultUuid={vault?.uuid} onCloseDialog={closeVaultModal} />
|
<EditVaultModalContent
|
||||||
|
creatingSharedVault={creatingSharedVault}
|
||||||
|
existingVaultUuid={vault?.uuid}
|
||||||
|
onCloseDialog={closeVaultModal}
|
||||||
|
/>
|
||||||
</ModalOverlay>
|
</ModalOverlay>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export const useVault = (vault: VaultListingInterface) => {
|
|||||||
|
|
||||||
const isCurrentUserAdmin = !vault.isSharedVaultListing()
|
const isCurrentUserAdmin = !vault.isSharedVaultListing()
|
||||||
? true
|
? true
|
||||||
: application.vaultUsers.isCurrentUserSharedVaultAdmin(vault)
|
: application.vaultUsers.isCurrentUserSharedVaultOwner(vault)
|
||||||
|
|
||||||
const ensureVaultIsUnlocked = useCallback(async () => {
|
const ensureVaultIsUnlocked = useCallback(async () => {
|
||||||
if (!application.vaultLocks.isVaultLocked(vault)) {
|
if (!application.vaultLocks.isVaultLocked(vault)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user