Compare commits

...
Author SHA1 Message Date
StandardNotes CI e4b858f2e8 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].7
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected].8
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].5
 - @standardnotes/[email protected].2
2023-07-12 12:22:07 +00:00
Karol Sójko 325737bfbd chore: fix ContentType usage (#2353)
* chore: fix ContentType usage

* chore: fix specs
2023-07-12 13:53:29 +02:00
StandardNotes CI d057cdff84 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
2023-07-12 10:06:57 +00:00
Aman Harwara 0528c06ce8 chore: release 2023-07-12 15:05:45 +05:30
StandardNotes CI bd906f2a12 chore(release): publish
- @standardnotes/[email protected].1
 - @standardnotes/[email protected]
2023-07-12 09:06:16 +00:00
Aman Harwara 669b395709 chore: fix crash on ios 2023-07-12 13:08:08 +05:30
StandardNotes CI da4967434a chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
2023-07-11 19:40:10 +00:00
Aman Harwara 96897163fb chore: update lexical 2023-07-12 00:42:26 +05:30
Aman Harwara 3dc179c7b0 feat: On Android, you can now share text & files from other apps directly into Standard Notes (#2352) 2023-07-12 00:16:32 +05:30
316 changed files with 1975 additions and 1251 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.26.26](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/api
## [1.26.25](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-11)
**Note:** Version bump only for package @standardnotes/api
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api",
"version": "1.26.25",
"version": "1.26.26",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -36,8 +36,8 @@
"typescript": "*"
},
"dependencies": {
"@standardnotes/common": "^1.48.3",
"@standardnotes/domain-core": "^1.12.0",
"@standardnotes/common": "^1.50.0",
"@standardnotes/domain-core": "^1.22.0",
"@standardnotes/models": "workspace:*",
"@standardnotes/responses": "workspace:*",
"@standardnotes/security": "^1.7.6",
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.84](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.83](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.82](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-11)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.81](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-11)
**Note:** Version bump only for package @standardnotes/clipper
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@standardnotes/clipper",
"description": "Web clipper browser extension for Standard Notes",
"version": "1.1.81",
"version": "1.1.84",
"private": true,
"scripts": {
"build-mv2": "yarn clean && webpack --config ./webpack.config.prod.js",
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.108.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/desktop
## [3.108.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/desktop
## [3.108.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-11)
**Note:** Version bump only for package @standardnotes/desktop
## [3.108.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-11)
**Note:** Version bump only for package @standardnotes/desktop
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@standardnotes/desktop",
"main": "./app/dist/index.js",
"version": "3.108.12",
"version": "3.108.15",
"license": "AGPL-3.0-or-later",
"author": "Standard Notes.",
"private": true,
@@ -35,7 +35,7 @@
},
"dependencies": {
"@electron/remote": "^2.0.9",
"@standardnotes/domain-core": "^1.18.0",
"@standardnotes/domain-core": "^1.22.0",
"@standardnotes/electron-clear-data": "1.1.1",
"@standardnotes/web": "workspace:*",
"axios": "^1.1.3",
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.49](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/encryption
## [1.21.48](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-06)
**Note:** Version bump only for package @standardnotes/encryption
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/encryption",
"version": "1.21.48",
"version": "1.21.49",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -28,7 +28,8 @@
"typescript": "*"
},
"dependencies": {
"@standardnotes/common": "^1.48.3",
"@standardnotes/common": "^1.50.0",
"@standardnotes/domain-core": "^1.22.0",
"@standardnotes/models": "workspace:*",
"@standardnotes/responses": "workspace:*",
"@standardnotes/sncrypto-common": "workspace:*",
@@ -1,4 +1,5 @@
import { ContentType, ProtocolVersion } from '@standardnotes/common'
import { ProtocolVersion } from '@standardnotes/common'
import { ContentType } from '@standardnotes/domain-core'
import {
ConflictStrategy,
DecryptedItem,
@@ -10,7 +11,7 @@ import {
} from '@standardnotes/models'
export function isItemsKey(x: unknown): x is ItemsKeyInterface {
return (x as ItemsKeyInterface).content_type === ContentType.ItemsKey
return (x as ItemsKeyInterface).content_type === ContentType.TYPES.ItemsKey
}
/**
@@ -1,6 +1,10 @@
import { ContentType } from '@standardnotes/common'
import { DecryptedItemMutator, ItemsKeyContent, RegisterItemClass } from '@standardnotes/models'
import { ContentType } from '@standardnotes/domain-core'
import { SNItemsKey } from './ItemsKey'
import { ItemsKeyMutator } from './ItemsKeyMutator'
RegisterItemClass(ContentType.ItemsKey, SNItemsKey, ItemsKeyMutator as unknown as DecryptedItemMutator<ItemsKeyContent>)
RegisterItemClass(
ContentType.TYPES.ItemsKey,
SNItemsKey,
ItemsKeyMutator as unknown as DecryptedItemMutator<ItemsKeyContent>,
)
@@ -1,4 +1,5 @@
import { ContentType, ProtocolVersion } from '@standardnotes/common'
import { ProtocolVersion } from '@standardnotes/common'
import { ContentType } from '@standardnotes/domain-core'
import {
ConflictStrategy,
DecryptedItem,
@@ -10,7 +11,7 @@ import {
} from '@standardnotes/models'
export function isKeySystemItemsKey(x: unknown): x is KeySystemItemsKeyInterface {
return (x as KeySystemItemsKeyInterface).content_type === ContentType.KeySystemItemsKey
return (x as KeySystemItemsKeyInterface).content_type === ContentType.TYPES.KeySystemItemsKey
}
/**
@@ -1,10 +1,11 @@
import { ContentType } from '@standardnotes/common'
import { DecryptedItemMutator, KeySystemItemsKeyContent, RegisterItemClass } from '@standardnotes/models'
import { ContentType } from '@standardnotes/domain-core'
import { KeySystemItemsKey } from './KeySystemItemsKey'
import { KeySystemItemsKeyMutator } from './KeySystemItemsKeyMutator'
RegisterItemClass(
ContentType.KeySystemItemsKey,
ContentType.TYPES.KeySystemItemsKey,
KeySystemItemsKey,
KeySystemItemsKeyMutator as unknown as DecryptedItemMutator<KeySystemItemsKeyContent>,
)
@@ -1,4 +1,4 @@
import { ContentType, ProtocolVersion } from '@standardnotes/common'
import { ProtocolVersion } from '@standardnotes/common'
import {
DecryptedPayload,
FillItemContentSpecialized,
@@ -9,13 +9,14 @@ import {
} from '@standardnotes/models'
import { UuidGenerator } from '@standardnotes/utils'
import { SNRootKey } from './RootKey'
import { ContentType } from '@standardnotes/domain-core'
export function CreateNewRootKey<K extends RootKeyInterface>(content: RootKeyContentSpecialized): K {
const uuid = UuidGenerator.GenerateUuid()
const payload = new DecryptedPayload<RootKeyContent>({
uuid: uuid,
content_type: ContentType.RootKey,
content_type: ContentType.TYPES.RootKey,
content: FillRootKeyContent(content),
...PayloadTimestampDefaults(),
})
@@ -1,4 +1,4 @@
import { ContentType, KeyParamsOrigination, ProtocolVersion, ProtocolVersionLength } from '@standardnotes/common'
import { KeyParamsOrigination, ProtocolVersion, ProtocolVersionLength } from '@standardnotes/common'
import {
CreateDecryptedItemFromPayload,
DecryptedPayload,
@@ -32,6 +32,7 @@ import { PublicKeySet } from '../Types/PublicKeySet'
import { AsymmetricDecryptResult } from '../Types/AsymmetricDecryptResult'
import { AsymmetricSignatureVerificationDetachedResult } from '../Types/AsymmetricSignatureVerificationDetachedResult'
import { AsyncOperatorInterface } from '../OperatorInterface/AsyncOperatorInterface'
import { ContentType } from '@standardnotes/domain-core'
const NO_IV = '00000000000000000000000000000000'
@@ -71,7 +72,7 @@ export class SNProtocolOperator001 implements OperatorInterface, AsyncOperatorIn
public createItemsKey(): ItemsKeyInterface {
const payload = new DecryptedPayload({
uuid: UuidGenerator.GenerateUuid(),
content_type: ContentType.ItemsKey,
content_type: ContentType.TYPES.ItemsKey,
content: this.generateNewItemsKeyContent(),
...PayloadTimestampDefaults(),
})
@@ -1,5 +1,6 @@
import * as Common from '@standardnotes/common'
import * as Models from '@standardnotes/models'
import { ContentType } from '@standardnotes/domain-core'
import { ItemContent, PayloadTimestampDefaults } from '@standardnotes/models'
import * as Utils from '@standardnotes/utils'
import { UuidGenerator } from '@standardnotes/utils'
@@ -44,7 +45,7 @@ export class SNProtocolOperator002 extends SNProtocolOperator001 {
public override createItemsKey(): Models.ItemsKeyInterface {
const payload = new Models.DecryptedPayload({
uuid: UuidGenerator.GenerateUuid(),
content_type: Common.ContentType.ItemsKey,
content_type: ContentType.TYPES.ItemsKey,
content: this.generateNewItemsKeyContent(),
...PayloadTimestampDefaults(),
})
@@ -1,4 +1,4 @@
import { ContentType, KeyParamsOrigination, ProtocolVersion } from '@standardnotes/common'
import { KeyParamsOrigination, ProtocolVersion } from '@standardnotes/common'
import {
CreateDecryptedItemFromPayload,
DecryptedPayload,
@@ -14,6 +14,7 @@ import { CreateNewRootKey } from '../../Keys/RootKey/Functions'
import { Create003KeyParams } from '../../Keys/RootKey/KeyParamsFunctions'
import { SNRootKeyParams } from '../../Keys/RootKey/RootKeyParams'
import { SNProtocolOperator002 } from '../002/Operator002'
import { ContentType } from '@standardnotes/domain-core'
/**
* @legacy
@@ -46,7 +47,7 @@ export class SNProtocolOperator003 extends SNProtocolOperator002 {
const content = this.generateNewItemsKeyContent()
const payload = new DecryptedPayload({
uuid: UuidGenerator.GenerateUuid(),
content_type: ContentType.ItemsKey,
content_type: ContentType.TYPES.ItemsKey,
content: FillItemContent(content),
...PayloadTimestampDefaults(),
})
@@ -1,9 +1,10 @@
import { ContentType, ProtocolVersion } from '@standardnotes/common'
import { ProtocolVersion } from '@standardnotes/common'
import { DecryptedPayload, ItemContent, ItemsKeyContent, PayloadTimestampDefaults } from '@standardnotes/models'
import { SNItemsKey } from '../../Keys/ItemsKey/ItemsKey'
import { SNProtocolOperator004 } from './Operator004'
import { getMockedCrypto } from './MockedCrypto'
import { deconstructEncryptedPayloadString } from './V004AlgorithmHelpers'
import { ContentType } from '@standardnotes/domain-core'
describe('operator 004', () => {
const crypto = getMockedCrypto()
@@ -31,7 +32,7 @@ describe('operator 004', () => {
it('should generateEncryptedParameters', () => {
const payload = {
uuid: '123',
content_type: ContentType.Note,
content_type: ContentType.TYPES.Note,
content: { foo: 'bar' } as unknown as jest.Mocked<ItemContent>,
...PayloadTimestampDefaults(),
} as jest.Mocked<DecryptedPayload>
@@ -39,7 +40,7 @@ describe('operator 004', () => {
const key = new SNItemsKey(
new DecryptedPayload<ItemsKeyContent>({
uuid: 'key-456',
content_type: ContentType.ItemsKey,
content_type: ContentType.TYPES.ItemsKey,
content: {
itemsKey: 'secret',
version: ProtocolVersion.V004,
@@ -56,7 +57,7 @@ describe('operator 004', () => {
key_system_identifier: undefined,
shared_vault_uuid: undefined,
content: '004:random-string:<e>{"foo"|"bar"}<e>:base64-{"u"|"123","v"|"004"}:base64-{}',
content_type: ContentType.Note,
content_type: ContentType.TYPES.Note,
enc_item_key: '004:random-string:<e>random-string<e>:base64-{"u"|"123","v"|"004"}:base64-{}',
version: '004',
})
@@ -13,7 +13,7 @@ import {
RootKeyInterface,
KeySystemRootKeyParamsInterface,
} from '@standardnotes/models'
import { ContentType, KeyParamsOrigination, ProtocolVersion } from '@standardnotes/common'
import { KeyParamsOrigination, ProtocolVersion } from '@standardnotes/common'
import { HexString, PkcKeyPair, PureCryptoInterface, Utf8String } from '@standardnotes/sncrypto-common'
import { V004Algorithm } from '../../Algorithm'
import { SNRootKeyParams } from '../../Keys/RootKey/RootKeyParams'
@@ -48,6 +48,7 @@ import { AsymmetricSignatureVerificationDetachedResult } from '../Types/Asymmetr
import { AsymmetricSignatureVerificationDetachedUseCase } from './UseCase/Asymmetric/AsymmetricSignatureVerificationDetached'
import { DeriveKeySystemRootKeyUseCase } from './UseCase/KeySystem/DeriveKeySystemRootKey'
import { SyncOperatorInterface } from '../OperatorInterface/SyncOperatorInterface'
import { ContentType } from '@standardnotes/domain-core'
export class SNProtocolOperator004 implements OperatorInterface, SyncOperatorInterface {
constructor(protected readonly crypto: PureCryptoInterface) {}
@@ -76,7 +77,7 @@ export class SNProtocolOperator004 implements OperatorInterface, SyncOperatorInt
public createItemsKey(): ItemsKeyInterface {
const payload = new DecryptedPayload({
uuid: UuidGenerator.GenerateUuid(),
content_type: ContentType.ItemsKey,
content_type: ContentType.TYPES.ItemsKey,
content: this.generateNewItemsKeyContent(),
key_system_identifier: undefined,
shared_vault_uuid: undefined,
@@ -10,7 +10,8 @@ import {
} from '@standardnotes/models'
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
import { V004Algorithm } from '../../../../Algorithm'
import { ContentType, ProtocolVersion } from '@standardnotes/common'
import { ProtocolVersion } from '@standardnotes/common'
import { ContentType } from '@standardnotes/domain-core'
export class CreateKeySystemItemsKeyUseCase {
constructor(private readonly crypto: PureCryptoInterface) {}
@@ -31,7 +32,7 @@ export class CreateKeySystemItemsKeyUseCase {
const transferPayload: DecryptedTransferPayload = {
uuid: dto.uuid,
content_type: ContentType.KeySystemItemsKey,
content_type: ContentType.TYPES.KeySystemItemsKey,
key_system_identifier: dto.keySystemIdentifier,
shared_vault_uuid: dto.sharedVaultUuid,
content: content,
@@ -12,7 +12,8 @@ import {
PayloadTimestampDefaults,
KeySystemRootKeyParamsInterface,
} from '@standardnotes/models'
import { ContentType, ProtocolVersion } from '@standardnotes/common'
import { ProtocolVersion } from '@standardnotes/common'
import { ContentType } from '@standardnotes/domain-core'
export class DeriveKeySystemRootKeyUseCase {
constructor(private readonly crypto: PureCryptoInterface) {}
@@ -44,7 +45,7 @@ export class DeriveKeySystemRootKeyUseCase {
const payload = new DecryptedPayload<KeySystemRootKeyContent>({
uuid: uuid,
content_type: ContentType.KeySystemRootKey,
content_type: ContentType.TYPES.KeySystemRootKey,
content: FillItemContentSpecialized(content),
...PayloadTimestampDefaults(),
})
@@ -1,5 +1,5 @@
import { CreateAnyKeyParams } from '../../../../Keys/RootKey/KeyParamsFunctions'
import { AnyKeyParamsContent, ContentType, ProtocolVersion } from '@standardnotes/common'
import { AnyKeyParamsContent, ProtocolVersion } from '@standardnotes/common'
import { GenerateAuthenticatedDataUseCase } from './GenerateAuthenticatedData'
import {
DecryptedPayloadInterface,
@@ -8,6 +8,7 @@ import {
RootKeyInterface,
} from '@standardnotes/models'
import { KeySystemItemsKey } from '../../../../Keys/KeySystemItemsKey/KeySystemItemsKey'
import { ContentType } from '@standardnotes/domain-core'
describe('generate authenticated data use case', () => {
let usecase: GenerateAuthenticatedDataUseCase
@@ -19,7 +20,7 @@ describe('generate authenticated data use case', () => {
it('should include key params if payload being encrypted is an items key', () => {
const payload = {
uuid: '123',
content_type: ContentType.ItemsKey,
content_type: ContentType.TYPES.ItemsKey,
} as jest.Mocked<DecryptedPayloadInterface>
const keyParams = CreateAnyKeyParams({
@@ -42,7 +43,7 @@ describe('generate authenticated data use case', () => {
it('should include root key params if payload is a key system items key', () => {
const payload = {
uuid: '123',
content_type: ContentType.KeySystemItemsKey,
content_type: ContentType.TYPES.KeySystemItemsKey,
shared_vault_uuid: 'shared-vault-uuid-123',
key_system_identifier: 'key-system-identifier-123',
} as jest.Mocked<DecryptedPayloadInterface>
@@ -52,7 +53,7 @@ describe('generate authenticated data use case', () => {
keyParams: {
seed: 'seed-123',
},
content_type: ContentType.KeySystemRootKey,
content_type: ContentType.TYPES.KeySystemRootKey,
token: '123',
} as jest.Mocked<KeySystemRootKeyInterface>
@@ -70,7 +71,7 @@ describe('generate authenticated data use case', () => {
it('should include key system identifier and shared vault uuid', () => {
const payload = {
uuid: '123',
content_type: ContentType.Note,
content_type: ContentType.TYPES.Note,
shared_vault_uuid: 'shared-vault-uuid-123',
key_system_identifier: 'key-system-identifier-123',
} as jest.Mocked<DecryptedPayloadInterface>
@@ -78,7 +79,7 @@ describe('generate authenticated data use case', () => {
const itemsKey = {
creationTimestamp: 123,
keyVersion: ProtocolVersion.V004,
content_type: ContentType.KeySystemItemsKey,
content_type: ContentType.TYPES.KeySystemItemsKey,
} as jest.Mocked<KeySystemItemsKey>
const authenticatedData = usecase.execute(payload, itemsKey)
@@ -94,11 +95,11 @@ describe('generate authenticated data use case', () => {
it('should include only uuid and version if non-keysystem item with items key', () => {
const payload = {
uuid: '123',
content_type: ContentType.Note,
content_type: ContentType.TYPES.Note,
} as jest.Mocked<DecryptedPayloadInterface>
const itemsKey = {
content_type: ContentType.ItemsKey,
content_type: ContentType.TYPES.ItemsKey,
} as jest.Mocked<ItemsKeyInterface>
const authenticatedData = usecase.execute(payload, itemsKey)
@@ -1,10 +1,10 @@
import { PkcKeyPair, PureCryptoInterface } from '@standardnotes/sncrypto-common'
import { getMockedCrypto } from '../../MockedCrypto'
import { GenerateDecryptedParametersUseCase } from './GenerateDecryptedParameters'
import { ContentType } from '@standardnotes/common'
import { DecryptedPayloadInterface, ItemsKeyInterface } from '@standardnotes/models'
import { GenerateEncryptedParametersUseCase } from './GenerateEncryptedParameters'
import { EncryptedInputParameters, EncryptedOutputParameters } from '../../../../Types/EncryptedParameters'
import { ContentType } from '@standardnotes/domain-core'
describe('generate decrypted parameters usecase', () => {
let crypto: PureCryptoInterface
@@ -18,7 +18,7 @@ describe('generate decrypted parameters usecase', () => {
itemsKey = {
uuid: 'items-key-id',
itemsKey: 'items-key',
content_type: ContentType.ItemsKey,
content_type: ContentType.TYPES.ItemsKey,
} as jest.Mocked<ItemsKeyInterface>
})
@@ -28,7 +28,7 @@ describe('generate decrypted parameters usecase', () => {
content: {
text: plaintext,
},
content_type: ContentType.Note,
content_type: ContentType.TYPES.Note,
} as unknown as jest.Mocked<DecryptedPayloadInterface>
const encryptedParametersUsecase = new GenerateEncryptedParametersUseCase(crypto)
@@ -1,6 +1,6 @@
import { PkcKeyPair, PureCryptoInterface } from '@standardnotes/sncrypto-common'
import { getMockedCrypto } from '../../MockedCrypto'
import { AnyKeyParamsContent, ContentType, ProtocolVersion } from '@standardnotes/common'
import { AnyKeyParamsContent, ProtocolVersion } from '@standardnotes/common'
import { GenerateEncryptedParametersUseCase } from './GenerateEncryptedParameters'
import {
DecryptedPayloadInterface,
@@ -11,6 +11,7 @@ import {
import { deconstructEncryptedPayloadString } from '../../V004AlgorithmHelpers'
import { ParseConsistentBase64JsonPayloadUseCase } from '../Utils/ParseConsistentBase64JsonPayload'
import { SymmetricItemAdditionalData } from '../../../../Types/EncryptionAdditionalData'
import { ContentType } from '@standardnotes/domain-core'
describe('generate encrypted parameters usecase', () => {
let crypto: PureCryptoInterface
@@ -29,20 +30,20 @@ describe('generate encrypted parameters usecase', () => {
title: 'title',
text: 'text',
},
content_type: ContentType.Note,
content_type: ContentType.TYPES.Note,
} as unknown as jest.Mocked<DecryptedPayloadInterface>
const itemsKey = {
uuid: 'items-key-id',
itemsKey: 'items-key',
content_type: ContentType.ItemsKey,
content_type: ContentType.TYPES.ItemsKey,
} as jest.Mocked<ItemsKeyInterface>
const result = usecase.execute(decrypted, itemsKey)
expect(result).toEqual({
uuid: '123',
content_type: ContentType.Note,
content_type: ContentType.TYPES.Note,
items_key_id: 'items-key-id',
content: expect.any(String),
enc_item_key: expect.any(String),
@@ -57,7 +58,7 @@ describe('generate encrypted parameters usecase', () => {
content: {
foo: 'bar',
},
content_type: ContentType.ItemsKey,
content_type: ContentType.TYPES.ItemsKey,
} as unknown as jest.Mocked<DecryptedPayloadInterface>
const rootKey = {
@@ -66,7 +67,7 @@ describe('generate encrypted parameters usecase', () => {
keyParams: {
content: {} as jest.Mocked<AnyKeyParamsContent>,
},
content_type: ContentType.RootKey,
content_type: ContentType.TYPES.RootKey,
} as jest.Mocked<RootKeyInterface>
const result = usecase.execute(decrypted, rootKey)
@@ -80,13 +81,13 @@ describe('generate encrypted parameters usecase', () => {
content: {
foo: 'bar',
},
content_type: ContentType.KeySystemItemsKey,
content_type: ContentType.TYPES.KeySystemItemsKey,
} as unknown as jest.Mocked<DecryptedPayloadInterface>
const rootKey = {
uuid: 'items-key-id',
itemsKey: 'items-key',
content_type: ContentType.KeySystemRootKey,
content_type: ContentType.TYPES.KeySystemRootKey,
} as jest.Mocked<KeySystemRootKeyInterface>
const result = usecase.execute(decrypted, rootKey)
@@ -111,13 +112,13 @@ describe('generate encrypted parameters usecase', () => {
title: 'title',
text: 'text',
},
content_type: ContentType.Note,
content_type: ContentType.TYPES.Note,
} as unknown as jest.Mocked<DecryptedPayloadInterface>
const itemsKey = {
uuid: 'items-key-id',
itemsKey: 'items-key',
content_type: ContentType.ItemsKey,
content_type: ContentType.TYPES.ItemsKey,
} as jest.Mocked<ItemsKeyInterface>
const result = usecase.execute(decrypted, itemsKey, signingKeyPair)
@@ -1,11 +1,11 @@
import { ContentType, ProtocolVersion } from '@standardnotes/common'
import { ProtocolVersion } from '@standardnotes/common'
import { EncryptedPayloadInterface, DecryptedPayloadInterface, PersistentSignatureData } from '@standardnotes/models'
import { DecryptedParameters } from './DecryptedParameters'
export type EncryptedOutputParameters = {
uuid: string
content: string
content_type: ContentType
content_type: string
items_key_id: string | undefined
enc_item_key: string
version: ProtocolVersion
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.59.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/features
## [1.59.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-30)
**Note:** Version bump only for package @standardnotes/features
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/features",
"version": "1.59.6",
"version": "1.59.7",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -25,8 +25,8 @@
"test": "jest"
},
"dependencies": {
"@standardnotes/common": "^1.48.3",
"@standardnotes/domain-core": "^1.12.0",
"@standardnotes/common": "^1.50.0",
"@standardnotes/domain-core": "^1.22.0",
"@standardnotes/security": "^1.7.6",
"reflect-metadata": "^0.1.13"
},
@@ -1,7 +1,6 @@
import { ContentType } from '@standardnotes/common'
import { ComponentAction } from './ComponentAction'
export type ComponentPermission = {
name: ComponentAction
content_types?: ContentType[]
content_types?: string[]
}
@@ -1,5 +1,4 @@
import { ComponentPermission } from '../Component/ComponentPermission'
import { ContentType } from '@standardnotes/common'
import { ComponentArea } from '../Component/ComponentArea'
import { PermissionName } from '../Permission/PermissionName'
import { FeatureIdentifier } from './FeatureIdentifier'
@@ -51,7 +50,7 @@ export type ClientFeatureDescription = RoleFields & {
export type ComponentFeatureDescription = BaseFeatureDescription & {
/** The relative path of the index.html file or the main css file if theme, within the component folder itself */
index_path: string
content_type: ContentType
content_type: string
area: ComponentArea
}
@@ -1,4 +1,4 @@
import { ContentType } from '@standardnotes/common'
import { ContentType, RoleName } from '@standardnotes/domain-core'
import {
EditorFeatureDescription,
IframeComponentFeatureDescription,
@@ -10,7 +10,6 @@ import { NoteType } from '../Component/NoteType'
import { FillEditorComponentDefaults } from './Utilities/FillEditorComponentDefaults'
import { ComponentAction } from '../Component/ComponentAction'
import { ComponentArea } from '../Component/ComponentArea'
import { RoleName } from '@standardnotes/domain-core'
export function GetDeprecatedFeatures(): FeatureDescription[] {
const bold: EditorFeatureDescription = FillEditorComponentDefaults({
@@ -21,14 +20,14 @@ export function GetDeprecatedFeatures(): FeatureDescription[] {
component_permissions: [
{
name: ComponentAction.StreamContextItem,
content_types: [ContentType.Note],
content_types: [ContentType.TYPES.Note],
},
{
name: ComponentAction.StreamItems,
content_types: [
ContentType.FilesafeCredentials,
ContentType.FilesafeFileMetadata,
ContentType.FilesafeIntegration,
ContentType.TYPES.FilesafeCredentials,
ContentType.TYPES.FilesafeFileMetadata,
ContentType.TYPES.FilesafeIntegration,
],
},
],
@@ -101,14 +100,14 @@ export function GetDeprecatedFeatures(): FeatureDescription[] {
component_permissions: [
{
name: ComponentAction.StreamContextItem,
content_types: [ContentType.Note],
content_types: [ContentType.TYPES.Note],
},
{
name: ComponentAction.StreamItems,
content_types: [
ContentType.FilesafeCredentials,
ContentType.FilesafeFileMetadata,
ContentType.FilesafeIntegration,
ContentType.TYPES.FilesafeCredentials,
ContentType.TYPES.FilesafeFileMetadata,
ContentType.TYPES.FilesafeIntegration,
],
},
],
@@ -1,5 +1,6 @@
import { ContentType } from '@standardnotes/domain-core'
import { ComponentAction } from '../../Component/ComponentAction'
import { ContentType } from '@standardnotes/common'
import { EditorFeatureDescription } from '../../Feature/FeatureDescription'
import { ComponentArea } from '../../Component/ComponentArea'
@@ -16,12 +17,12 @@ export function FillEditorComponentDefaults(
component.component_permissions = [
{
name: ComponentAction.StreamContextItem,
content_types: [ContentType.Note],
content_types: [ContentType.TYPES.Note],
},
]
}
component.content_type = ContentType.Component
component.content_type = ContentType.TYPES.Component
if (!component.area) {
component.area = ComponentArea.Editor
}
@@ -1,4 +1,5 @@
import { ContentType } from '@standardnotes/common'
import { ContentType } from '@standardnotes/domain-core'
import { ThemeFeatureDescription } from '../../Feature/FeatureDescription'
import { ComponentArea } from '../../Component/ComponentArea'
@@ -11,7 +12,7 @@ export function FillThemeComponentDefaults(
theme.index_path = 'index.css'
}
theme.content_type = ContentType.Theme
theme.content_type = ContentType.TYPES.Theme
if (!theme.area) {
theme.area = ComponentArea.Themes
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.28.58](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.28.57](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-06)
**Note:** Version bump only for package @standardnotes/filepicker
@@ -39,7 +39,7 @@ export class ClassicFileApi {
downloadFileBytes = async (remoteIdentifier: string): Promise<Uint8Array> => {
console.log('Downloading file', remoteIdentifier)
const file = this.application['itemManager']
.getItems(ContentType.File)
.getItems(ContentType.TYPES.File)
.find((file: FileItem) => file.remoteIdentifier === remoteIdentifier)
let receivedBytes = new Uint8Array()
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/filepicker",
"version": "1.28.57",
"version": "1.28.58",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -26,7 +26,7 @@
"typescript": "*"
},
"dependencies": {
"@standardnotes/common": "^1.48.3",
"@standardnotes/common": "^1.50.0",
"@standardnotes/files": "workspace:*",
"@standardnotes/utils": "workspace:*",
"@types/wicg-file-system-access": "^2020.9.5",
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.16.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/files
## [1.16.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-06)
**Note:** Version bump only for package @standardnotes/files
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files",
"version": "1.16.3",
"version": "1.16.4",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -28,7 +28,7 @@
"typescript": "*"
},
"dependencies": {
"@standardnotes/common": "^1.48.3",
"@standardnotes/common": "^1.50.0",
"@standardnotes/encryption": "workspace:*",
"@standardnotes/models": "workspace:*",
"@standardnotes/responses": "workspace:*",
+18
View File
@@ -3,6 +3,24 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.55.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/mobile
## [3.55.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/mobile
## [3.55.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/mobile
# [3.55.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-11)
### Features
* On Android, you can now share text & files from other apps directly into Standard Notes ([#2352](https://github.com/standardnotes/app/issues/2352)) ([3dc179c](https://github.com/standardnotes/app/commit/3dc179c7b0779ef0f2857b7f9c994ea9d5385720))
## [3.54.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-11)
**Note:** Version bump only for package @standardnotes/mobile
@@ -43,6 +43,16 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
</application>
@@ -1,6 +1,7 @@
package com.standardnotes;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.content.res.Configuration;
@@ -54,4 +55,10 @@ public class MainActivity extends ReactActivity {
public void invokeDefaultOnBackPressed() {
moveTaskToBack(true);
}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
}
@@ -39,6 +39,7 @@ public class MainApplication extends Application implements ReactApplication {
packages.add(new Fido2ApiPackage());
packages.add(new CustomWebViewPackage());
packages.add(new ReceiveSharingIntentPackage());
return packages;
}
@@ -0,0 +1,171 @@
// Adapted from
// https://github.com/ajith-ab/react-native-receive-sharing-intent
package com.standardnotes;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
import java.util.ArrayList;
import java.util.Objects;
public class ReceiveSharingIntentHelper {
private Context context;
public ReceiveSharingIntentHelper(Application context) {
this.context = context;
}
public void sendFileNames(Context context, Intent intent, Promise promise) {
try {
String action = intent.getAction();
String type = intent.getType();
if (type == null) {
return;
}
if (!type.startsWith("text") && (Objects.equals(action, Intent.ACTION_SEND) || Objects.equals(action, Intent.ACTION_SEND_MULTIPLE))) {
WritableMap files = getMediaUris(intent, context);
if (files == null) return;
promise.resolve(files);
}
else if (type.startsWith("text") && Objects.equals(action, Intent.ACTION_SEND)) {
String text = null;
String subject = null;
try {
text = intent.getStringExtra(Intent.EXTRA_TEXT);
subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
} catch (Exception ignored) {}
WritableMap files;
if (text == null) {
files = getMediaUris(intent, context);
if (files == null) return;
}
else {
files = new WritableNativeMap();
WritableMap file = new WritableNativeMap();
file.putString("contentUri", null);
file.putString("fileName", null);
file.putString("extension", null);
if (text.startsWith("http")) {
file.putString("weblink", text);
file.putString("text", null);
} else {
file.putString("weblink", null);
file.putString("text", text);
}
file.putString("subject", subject);
files.putMap("0", file);
}
promise.resolve(files);
}
else if (Objects.equals(action, Intent.ACTION_VIEW)) {
String link = intent.getDataString();
WritableMap files = new WritableNativeMap();
WritableMap file = new WritableNativeMap();
file.putString("contentUri", null);
file.putString("mimeType", null);
file.putString("text", null);
file.putString("weblink", link);
file.putString("fileName", null);
file.putString("extension", null);
files.putMap("0", file);
promise.resolve(files);
}
else if (Objects.equals(action, Intent.ACTION_PROCESS_TEXT)) {
String text = null;
try {
text = intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT);
} catch (Exception ignored) {
}
WritableMap files = new WritableNativeMap();
WritableMap file = new WritableNativeMap();
file.putString("contentUri", null);
file.putString("fileName", null);
file.putString("extension", null);
file.putString("weblink", null);
file.putString("text", text);
files.putMap("0", file);
promise.resolve(files);
}
else {
promise.reject("error", "Invalid file type.");
}
} catch (Exception e) {
promise.reject("error", e.toString());
}
}
@SuppressLint("Range")
public WritableMap getMediaUris(Intent intent, Context context) {
if (intent == null) return null;
String subject = null;
try {
subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
} catch (Exception ignored) {
}
WritableMap files = new WritableNativeMap();
if (Objects.equals(intent.getAction(), Intent.ACTION_SEND)) {
WritableMap file = new WritableNativeMap();
Uri contentUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (contentUri == null) return null;
ContentResolver contentResolver = context.getContentResolver();
file.putString("mimeType", contentResolver.getType(contentUri));
Cursor queryResult = contentResolver.query(contentUri, null, null, null, null);
queryResult.moveToFirst();
file.putString("fileName", queryResult.getString(queryResult.getColumnIndex(OpenableColumns.DISPLAY_NAME)));
file.putString("contentUri", contentUri.toString());
file.putString("text", null);
file.putString("weblink", null);
file.putString("subject", subject);
files.putMap("0", file);
queryResult.close();
} else if (Objects.equals(intent.getAction(), Intent.ACTION_SEND_MULTIPLE)) {
ArrayList<Uri> contentUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (contentUris != null) {
int index = 0;
for (Uri uri : contentUris) {
WritableMap file = new WritableNativeMap();
ContentResolver contentResolver = context.getContentResolver();
// Based on https://developer.android.com/training/secure-file-sharing/retrieve-info
file.putString("mimeType", contentResolver.getType(uri));
Cursor queryResult = contentResolver.query(uri, null, null, null, null);
queryResult.moveToFirst();
file.putString("fileName", queryResult.getString(queryResult.getColumnIndex(OpenableColumns.DISPLAY_NAME)));
file.putString("contentUri", uri.toString());
file.putString("text", null);
file.putString("weblink", null);
file.putString("subject", subject);
files.putMap(Integer.toString(index), file);
queryResult.close();
index++;
}
}
}
return files;
}
public void clearFileNames(Intent intent) {
String type = intent.getType();
if (type == null) return;
if (type.startsWith("text")) {
intent.removeExtra(Intent.EXTRA_TEXT);
} else if (type.startsWith("image") || type.startsWith("video") || type.startsWith("application")) {
intent.removeExtra(Intent.EXTRA_STREAM);
}
}
}
@@ -0,0 +1,64 @@
// Adapted from
// https://github.com/ajith-ab/react-native-receive-sharing-intent
package com.standardnotes;
import android.app.Activity;
import android.app.Application;
import android.content.Intent;
import android.os.Build;
import androidx.annotation.RequiresApi;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
public class ReceiveSharingIntentModule extends ReactContextBaseJavaModule {
public final String Log_Tag = "ReceiveSharingIntent";
private final ReactApplicationContext reactContext;
private ReceiveSharingIntentHelper receiveSharingIntentHelper;
public ReceiveSharingIntentModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
Application applicationContext = (Application) reactContext.getApplicationContext();
receiveSharingIntentHelper = new ReceiveSharingIntentHelper(applicationContext);
}
protected void onNewIntent(Intent intent) {
Activity mActivity = getCurrentActivity();
if(mActivity == null) { return; }
mActivity.setIntent(intent);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@ReactMethod
public void getFileNames(Promise promise){
Activity mActivity = getCurrentActivity();
if(mActivity == null) { return; }
Intent intent = mActivity.getIntent();
if(intent == null) { return; }
receiveSharingIntentHelper.sendFileNames(reactContext, intent, promise);
mActivity.setIntent(null);
}
@ReactMethod
public void clearFileNames(){
Activity mActivity = getCurrentActivity();
if(mActivity == null) { return; }
Intent intent = mActivity.getIntent();
if(intent == null) { return; }
receiveSharingIntentHelper.clearFileNames(intent);
}
@Override
public String getName() {
return "ReceiveSharingIntent";
}
}
@@ -0,0 +1,27 @@
package com.standardnotes;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.standardnotes.ReceiveSharingIntentModule;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ReceiveSharingIntentPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ReceiveSharingIntentModule(reactContext));
return modules;
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/mobile",
"version": "3.54.16",
"version": "3.55.3",
"author": "Standard Notes.",
"private": true,
"license": "AGPL-3.0-or-later",
@@ -0,0 +1,4 @@
import { requireNativeComponent } from 'react-native'
import { NativeWebViewAndroid } from 'react-native-webview/lib/WebViewTypes'
export default requireNativeComponent('CustomWebView') as NativeWebViewAndroid
+26 -7
View File
@@ -2,6 +2,7 @@ import SNReactNative from '@standardnotes/react-native-utils'
import {
AppleIAPProductId,
AppleIAPReceipt,
ApplicationEvent,
ApplicationIdentifier,
DatabaseKeysLoadChunkResponse,
DatabaseLoadOptions,
@@ -57,11 +58,13 @@ export enum MobileDeviceEvent {
}
type MobileDeviceEventHandler = (event: MobileDeviceEvent) => void
type ApplicationEventHandler = (event: ApplicationEvent) => void
export class MobileDevice implements MobileDeviceInterface {
environment: Environment.Mobile = Environment.Mobile
platform: SNPlatform.Ios | SNPlatform.Android = Platform.OS === 'ios' ? SNPlatform.Ios : SNPlatform.Android
private eventObservers: MobileDeviceEventHandler[] = []
private applicationEventObservers: ApplicationEventHandler[] = []
private mobileDeviceEventObservers: MobileDeviceEventHandler[] = []
public isDarkMode = false
public statusBarBgColor: string | undefined
private componentUrls: Map<UuidString, string> = new Map()
@@ -346,13 +349,23 @@ export class MobileDevice implements MobileDeviceInterface {
}
performSoftReset() {
this.notifyEvent(MobileDeviceEvent.RequestsWebViewReload)
this.notifyMobileDeviceEvent(MobileDeviceEvent.RequestsWebViewReload)
}
addMobileWebEventReceiver(handler: MobileDeviceEventHandler): () => void {
this.eventObservers.push(handler)
addMobileDeviceEventReceiver(handler: MobileDeviceEventHandler): () => void {
this.mobileDeviceEventObservers.push(handler)
const thislessObservers = this.eventObservers
const thislessObservers = this.mobileDeviceEventObservers
return () => {
removeFromArray(thislessObservers, handler)
}
}
addApplicationEventReceiver(handler: ApplicationEventHandler): () => void {
this.applicationEventObservers.push(handler)
const thislessObservers = this.applicationEventObservers
return () => {
removeFromArray(thislessObservers, handler)
@@ -373,8 +386,14 @@ export class MobileDevice implements MobileDeviceInterface {
StatusBar.setBarStyle(this.isDarkMode ? 'light-content' : 'dark-content', animated)
}
private notifyEvent(event: MobileDeviceEvent): void {
for (const handler of this.eventObservers) {
private notifyMobileDeviceEvent(event: MobileDeviceEvent): void {
for (const handler of this.mobileDeviceEventObservers) {
handler(event)
}
}
notifyApplicationEvent(event: ApplicationEvent): void {
for (const handler of this.applicationEventObservers) {
handler(event)
}
}
+22 -7
View File
@@ -1,16 +1,16 @@
import { ReactNativeToWebEvent } from '@standardnotes/snjs'
import { ApplicationEvent, ReactNativeToWebEvent } from '@standardnotes/snjs'
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Button, Keyboard, Platform, requireNativeComponent, Text, View } from 'react-native'
import { Button, Keyboard, Platform, Text, View } from 'react-native'
import VersionInfo from 'react-native-version-info'
import { WebView, WebViewMessageEvent } from 'react-native-webview'
import { NativeWebViewAndroid, OnShouldStartLoadWithRequest } from 'react-native-webview/lib/WebViewTypes'
import { OnShouldStartLoadWithRequest } from 'react-native-webview/lib/WebViewTypes'
import { AndroidBackHandlerService } from './AndroidBackHandlerService'
import { AppStateObserverService } from './AppStateObserverService'
import { ColorSchemeObserverService } from './ColorSchemeObserverService'
import CustomAndroidWebView from './CustomAndroidWebView'
import { MobileDevice, MobileDeviceEvent } from './Lib/MobileDevice'
import { IsDev } from './Lib/Utils'
const CustomWebView: NativeWebViewAndroid = requireNativeComponent('CustomWebView')
import { ReceivedSharedItemsHandler } from './ReceivedSharedItemsHandler'
const LoggingEnabled = IsDev
@@ -110,7 +110,7 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
}, [webViewRef, stateService, device, androidBackHandlerService, colorSchemeService])
useEffect(() => {
const observer = device.addMobileWebEventReceiver((event) => {
const observer = device.addMobileDeviceEventReceiver((event) => {
if (event === MobileDeviceEvent.RequestsWebViewReload) {
destroyAndReload()
}
@@ -283,6 +283,21 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
const requireInlineMediaPlaybackForMomentsFeature = true
const requireMediaUserInteractionForMomentsFeature = false
const receivedSharedItemsHandler = useRef(new ReceivedSharedItemsHandler(webViewRef))
useEffect(() => {
const receivedSharedItemsHandlerInstance = receivedSharedItemsHandler.current
return () => {
receivedSharedItemsHandlerInstance.deinit()
}
}, [])
useEffect(() => {
return device.addApplicationEventReceiver((event) => {
if (event === ApplicationEvent.Launched) {
receivedSharedItemsHandler.current.setIsApplicationLaunched(true)
}
})
}, [device])
if (showAndroidWebviewUpdatePrompt) {
return (
<View
@@ -357,7 +372,7 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
overScrollMode="never"
nativeConfig={Platform.select({
android: {
component: CustomWebView,
component: CustomAndroidWebView,
},
})}
/>
@@ -0,0 +1,134 @@
import { ReactNativeToWebEvent } from '@standardnotes/snjs'
import { RefObject } from 'react'
import { AppState, NativeEventSubscription, NativeModules, Platform } from 'react-native'
import { readFile } from 'react-native-fs'
import WebView from 'react-native-webview'
const { ReceiveSharingIntent } = NativeModules
type ReceivedItem = {
contentUri?: string | null
fileName?: string | null
mimeType?: string | null
extension?: string | null
text?: string | null
weblink?: string | null
subject?: string | null
}
type ReceivedFile = ReceivedItem & {
contentUri: string
mimeType: string
}
type ReceivedWeblink = ReceivedItem & {
weblink: string
}
type ReceivedText = ReceivedItem & {
text: string
}
const isReceivedFile = (item: ReceivedItem): item is ReceivedFile => {
return !!item.contentUri && !!item.mimeType
}
const isReceivedWeblink = (item: ReceivedItem): item is ReceivedWeblink => {
return !!item.weblink
}
const isReceivedText = (item: ReceivedItem): item is ReceivedText => {
return !!item.text
}
export class ReceivedSharedItemsHandler {
private appStateEventSub: NativeEventSubscription | null = null
private receivedItemsQueue: ReceivedItem[] = []
private isApplicationLaunched = false
constructor(private webViewRef: RefObject<WebView>) {
if (Platform.OS === 'android') {
this.registerNativeEventSub()
}
}
setIsApplicationLaunched = (isApplicationLaunched: boolean) => {
this.isApplicationLaunched = isApplicationLaunched
if (isApplicationLaunched) {
this.handleItemsQueue().catch(console.error)
}
}
deinit() {
this.receivedItemsQueue = []
this.appStateEventSub?.remove()
}
private registerNativeEventSub = () => {
this.appStateEventSub = AppState.addEventListener('change', (state) => {
if (state === 'active') {
ReceiveSharingIntent.getFileNames()
.then(async (filesObject: Record<string, ReceivedItem>) => {
const items = Object.values(filesObject)
this.receivedItemsQueue.push(...items)
if (this.isApplicationLaunched) {
this.handleItemsQueue().catch(console.error)
}
})
.then(() => ReceiveSharingIntent.clearFileNames())
.catch(console.error)
}
})
}
handleItemsQueue = async () => {
if (!this.receivedItemsQueue.length) {
return
}
const item = this.receivedItemsQueue.shift()
if (!item) {
return
}
if (isReceivedFile(item)) {
const data = await readFile(item.contentUri, 'base64')
const file = {
name: item.fileName || item.contentUri,
data,
mimeType: item.mimeType,
}
this.webViewRef.current?.postMessage(
JSON.stringify({
reactNativeEvent: ReactNativeToWebEvent.ReceivedFile,
messageType: 'event',
messageData: file,
}),
)
} else if (isReceivedWeblink(item)) {
this.webViewRef.current?.postMessage(
JSON.stringify({
reactNativeEvent: ReactNativeToWebEvent.ReceivedText,
messageType: 'event',
messageData: {
title: item.subject || item.weblink,
text: item.weblink,
},
}),
)
} else if (isReceivedText(item)) {
this.webViewRef.current?.postMessage(
JSON.stringify({
reactNativeEvent: ReactNativeToWebEvent.ReceivedText,
messageType: 'event',
messageData: {
text: item.text,
},
}),
)
}
this.handleItemsQueue().catch(console.error)
}
}
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.46.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-12)
**Note:** Version bump only for package @standardnotes/models
## [1.46.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-07-06)
**Note:** Version bump only for package @standardnotes/models
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/models",
"version": "1.46.7",
"version": "1.46.8",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -22,7 +22,8 @@
"test": "jest"
},
"dependencies": {
"@standardnotes/common": "^1.48.3",
"@standardnotes/common": "^1.50.0",
"@standardnotes/domain-core": "^1.22.0",
"@standardnotes/features": "workspace:*",
"@standardnotes/responses": "workspace:*",
"@standardnotes/sncrypto-common": "workspace:^",
@@ -1,4 +1,3 @@
import { ContentType } from '@standardnotes/common'
import { ComponentPermission } from '@standardnotes/features'
import { IncomingComponentItemPayload } from './IncomingComponentItemPayload'
@@ -8,7 +7,7 @@ export type MessageData = Partial<{
/** Related to the stream-item-context action */
item?: IncomingComponentItemPayload
/** Related to the stream-items action */
content_types?: ContentType[]
content_types?: string[]
items?: IncomingComponentItemPayload[]
/** Related to the request-permission action */
permissions?: ComponentPermission[]
@@ -25,7 +24,7 @@ export type MessageData = Partial<{
/** Related to themes action */
themes?: string[]
/** Related to clear-selection action */
content_type?: ContentType
content_type?: string
/** Related to key-pressed action */
keyboardModifier?: KeyboardModifier
}>
@@ -1,9 +1,8 @@
import { ItemContent } from './../Content/ItemContent'
import { ContentType } from '@standardnotes/common'
export type OutgoingItemMessagePayload<C extends ItemContent = ItemContent> = {
uuid: string
content_type: ContentType
content_type: string
created_at: Date
updated_at: Date
deleted?: boolean
@@ -1,9 +1,8 @@
import { ContentType } from '@standardnotes/common'
import { ItemContent } from '../Content/ItemContent'
export interface ContextPayload<C extends ItemContent = ItemContent> {
uuid: string
content_type: ContentType
content_type: string
content: C | string | undefined
deleted: boolean
@@ -1,4 +1,3 @@
import { ContentType } from '@standardnotes/common'
import { DecryptedPayloadInterface, DeletedPayloadInterface, isDeletedPayload } from '../Payload'
/**
@@ -8,7 +7,7 @@ import { DecryptedPayloadInterface, DeletedPayloadInterface, isDeletedPayload }
* nothing else.
*/
export interface OfflineSyncSavedContextualPayload {
content_type: ContentType
content_type: string
created_at_timestamp: number
deleted: boolean
updated_at_timestamp?: number
@@ -1,6 +1,5 @@
import { useBoolean } from '@standardnotes/utils'
import { FilteredServerItem } from './FilteredServerItem'
import { ContentType } from '@standardnotes/common'
/**
* The saved sync item payload represents the payload we want to map
@@ -9,7 +8,7 @@ import { ContentType } from '@standardnotes/common'
* nothing else.
*/
export interface ServerSyncSavedContextualPayload {
content_type: ContentType
content_type: string
created_at_timestamp: number
created_at: Date
deleted: boolean
@@ -1,4 +1,3 @@
import { ContentType } from '@standardnotes/common'
import { dateToLocalizedString, deepFreeze } from '@standardnotes/utils'
import { TransferPayload } from './../../TransferPayload/Interfaces/TransferPayload'
import { ItemContentsDiffer } from '../../../Utilities/Item/ItemContentsDiffer'
@@ -36,7 +35,7 @@ export abstract class GenericItem<P extends PayloadInterface = PayloadInterface>
return this.payload.uuid
}
get content_type(): ContentType {
get content_type(): string {
return this.payload.content_type
}
@@ -1,4 +1,3 @@
import { ContentType } from '@standardnotes/common'
import { TransferPayload } from './../../TransferPayload/Interfaces/TransferPayload'
import { PayloadInterface } from '../../Payload/Interfaces/PayloadInterface'
import { PredicateInterface } from '../../../Runtime/Predicate/Interface'
@@ -21,7 +20,7 @@ export interface ItemInterface<P extends PayloadInterface = PayloadInterface> {
get last_edited_by_uuid(): string | undefined
get signatureData(): PersistentSignatureData | undefined
content_type: ContentType
content_type: string
created_at: Date
serverUpdatedAt: Date
serverUpdatedAtTimestamp: number | undefined
@@ -1,4 +1,3 @@
import { ContentType } from '@standardnotes/common'
import { deepFreeze, useBoolean } from '@standardnotes/utils'
import { PayloadInterface } from '../Interfaces/PayloadInterface'
import { PayloadSource } from '../Types/PayloadSource'
@@ -19,7 +18,7 @@ export abstract class PurePayload<T extends TransferPayload<C>, C extends ItemCo
{
readonly source: PayloadSource
readonly uuid: string
readonly content_type: ContentType
readonly content_type: string
readonly deleted: boolean
readonly content: C | string | undefined
@@ -1,5 +1,4 @@
import { SyncResolvedParams, SyncResolvedPayload } from './../../../Runtime/Deltas/Utilities/SyncResolvedPayload'
import { ContentType } from '@standardnotes/common'
import { ItemContent } from '../../Content/ItemContent'
import { TransferPayload } from '../../TransferPayload/Interfaces/TransferPayload'
import { PayloadSource } from '../Types/PayloadSource'
@@ -8,7 +7,7 @@ import { PersistentSignatureData } from '../../../Runtime/Encryption/PersistentS
export interface PayloadInterface<T extends TransferPayload = TransferPayload, C extends ItemContent = ItemContent> {
readonly source: PayloadSource
readonly uuid: string
readonly content_type: ContentType
readonly content_type: string
content: C | string | undefined
deleted: boolean
@@ -1,8 +1,7 @@
import { ContentType } from '@standardnotes/common'
import { ContentReferenceType } from './ContenteReferenceType'
export interface AnonymousReference {
uuid: string
content_type: ContentType
content_type: string
reference_type: ContentReferenceType
}
@@ -1,8 +1,7 @@
import { ContentType } from '@standardnotes/common'
import { AnonymousReference } from './AnonymousReference'
import { ContentReferenceType } from './ContenteReferenceType'
export interface FileToFileReference extends AnonymousReference {
content_type: ContentType.File
content_type: string
reference_type: ContentReferenceType.FileToFile
}
@@ -1,8 +1,7 @@
import { ContentType } from '@standardnotes/common'
import { AnonymousReference } from './AnonymousReference'
import { ContentReferenceType } from './ContenteReferenceType'
export interface FileToNoteReference extends AnonymousReference {
content_type: ContentType.Note
content_type: string
reference_type: ContentReferenceType.FileToNote
}
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ContentType } from '@standardnotes/common'
import { ContentType } from '@standardnotes/domain-core'
import { ItemInterface } from '../Item/Interfaces/ItemInterface'
import { ContentReferenceType } from './ContenteReferenceType'
import { ContentReference } from './ContentReference'
@@ -20,8 +20,8 @@ export const isLegacyTagToNoteReference = (
x: LegacyAnonymousReference,
currentItem: ItemInterface,
): x is LegacyTagToNoteReference => {
const isReferenceToANote = x.content_type === ContentType.Note
const isReferenceFromATag = currentItem.content_type === ContentType.Tag
const isReferenceToANote = x.content_type === ContentType.TYPES.Note
const isReferenceFromATag = currentItem.content_type === ContentType.TYPES.Tag
return isReferenceToANote && isReferenceFromATag
}
@@ -1,6 +1,5 @@
import { ContentType } from '@standardnotes/common'
import { LegacyAnonymousReference } from './LegacyAnonymousReference'
export interface LegacyTagToNoteReference extends LegacyAnonymousReference {
content_type: ContentType.Note
content_type: string
}
@@ -1,8 +1,7 @@
import { ContentType } from '@standardnotes/common'
import { AnonymousReference } from './AnonymousReference'
import { ContentReferenceType } from './ContenteReferenceType'
export interface NoteToNoteReference extends AnonymousReference {
content_type: ContentType.Note
content_type: string
reference_type: ContentReferenceType.NoteToNote
}

Some files were not shown because too many files have changed in this diff Show More