mirror of
https://github.com/standardnotes/server
synced 2026-10-12 15:13:39 -04:00
fix: Prevents client from bypassing item ownership check
This commit is contained in:
@@ -580,10 +580,10 @@ export class ContainerConfigLoader {
|
||||
.toConstantValue(
|
||||
new ItemSaveValidator([
|
||||
container.get(TYPES.Sync_OwnershipFilter),
|
||||
container.get(TYPES.Sync_SharedVaultFilter),
|
||||
container.get(TYPES.Sync_TimeDifferenceFilter),
|
||||
container.get(TYPES.Sync_ContentTypeFilter),
|
||||
container.get(TYPES.Sync_ContentFilter),
|
||||
container.get(TYPES.Sync_SharedVaultFilter),
|
||||
container.get(TYPES.Sync_SharedVaultSnjsFilter),
|
||||
]),
|
||||
)
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Item } from '../Item'
|
||||
import { OwnershipFilter } from './OwnershipFilter'
|
||||
import { Uuid, ContentType, Dates, Timestamps, UniqueEntityId } from '@standardnotes/domain-core'
|
||||
import { ItemHash } from '../ItemHash'
|
||||
import { SharedVaultAssociation } from '../../SharedVault/SharedVaultAssociation'
|
||||
|
||||
describe('OwnershipFilter', () => {
|
||||
let existingItem: Item
|
||||
@@ -60,7 +61,7 @@ describe('OwnershipFilter', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('should deffer to the shared vault filter if the item hash represents a shared vault item or existing item is a shared vault item', async () => {
|
||||
it('should not defer to the shared vault filter based on a client-supplied shared_vault_uuid alone', async () => {
|
||||
const itemHash = ItemHash.create({
|
||||
uuid: '2-3-4',
|
||||
content_type: ContentType.TYPES.Note,
|
||||
@@ -81,6 +82,56 @@ describe('OwnershipFilter', () => {
|
||||
snjsVersion: '2.200.0',
|
||||
})
|
||||
|
||||
expect(result).toEqual({
|
||||
passed: false,
|
||||
conflict: {
|
||||
unsavedItem: itemHash,
|
||||
type: 'uuid_conflict',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('should defer to the shared vault filter when the existing item is associated with a shared vault', async () => {
|
||||
const sharedVaultExistingItem = Item.create(
|
||||
{
|
||||
userUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(),
|
||||
updatedWithSession: null,
|
||||
content: 'foobar',
|
||||
contentType: ContentType.create(ContentType.TYPES.Note).getValue(),
|
||||
encItemKey: null,
|
||||
authHash: null,
|
||||
itemsKeyId: null,
|
||||
duplicateOf: null,
|
||||
deleted: false,
|
||||
dates: Dates.create(new Date(1616164633241311), new Date(1616164633241311)).getValue(),
|
||||
timestamps: Timestamps.create(1616164633241311, 1616164633241311).getValue(),
|
||||
sharedVaultAssociation: SharedVaultAssociation.create({
|
||||
lastEditedBy: Uuid.create('00000000-0000-0000-0000-000000000001').getValue(),
|
||||
sharedVaultUuid: Uuid.create('00000000-0000-0000-0000-000000000001').getValue(),
|
||||
}).getValue(),
|
||||
},
|
||||
new UniqueEntityId('00000000-0000-0000-0000-000000000000'),
|
||||
).getValue()
|
||||
const itemHash = ItemHash.create({
|
||||
uuid: '2-3-4',
|
||||
content_type: ContentType.TYPES.Note,
|
||||
user_uuid: '00000000-0000-0000-0000-000000000001',
|
||||
content: 'foobar',
|
||||
created_at: '2020-01-01T00:00:00.000Z',
|
||||
updated_at: '2020-01-01T00:00:00.000Z',
|
||||
created_at_timestamp: 123,
|
||||
updated_at_timestamp: 123,
|
||||
key_system_identifier: null,
|
||||
shared_vault_uuid: null,
|
||||
}).getValue()
|
||||
const result = await createFilter().check({
|
||||
userUuid: '00000000-0000-0000-0000-000000000001',
|
||||
apiVersion: ApiVersion.v20200115,
|
||||
itemHash,
|
||||
existingItem: sharedVaultExistingItem,
|
||||
snjsVersion: '2.200.0',
|
||||
})
|
||||
|
||||
expect(result).toEqual({
|
||||
passed: true,
|
||||
})
|
||||
|
||||
@@ -6,8 +6,7 @@ import { Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
export class OwnershipFilter implements ItemSaveRuleInterface {
|
||||
async check(dto: ItemSaveValidationDTO): Promise<ItemSaveRuleResult> {
|
||||
const deferToSharedVaultFilter =
|
||||
dto.existingItem?.isAssociatedWithASharedVault() || dto.itemHash.representsASharedVaultItem()
|
||||
const deferToSharedVaultFilter = dto.existingItem?.isAssociatedWithASharedVault() === true
|
||||
if (deferToSharedVaultFilter) {
|
||||
return {
|
||||
passed: true,
|
||||
|
||||
Reference in New Issue
Block a user