Compare commits

...
Author SHA1 Message Date
StandardNotes CI 6b774db222 chore(release): publish
- @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected].4
2023-01-09 06:23:12 +00:00
Karol SójkoandMo be028ff87b feat(snjs): add sign in with recovery codes use case (#2130)
* feat(snjs): add sign in with recovery codes use case

* fix(snjs): code review adjustments

* fix(snjs): remove unnecessary exposed getter

* fix(services): waiting for event handling

* fix: preferences test

Co-authored-by: Mo <[email protected]>
2023-01-09 06:52:56 +01:00
StandardNotes CI 5f09fc74da chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
2023-01-07 09:52:22 +00:00
Aman Harwara 340f4f7f09 fix: Fixed issue where search button would not show up in Files view 2023-01-07 14:50:06 +05:30
Aman Harwara 371a47d838 refactor: new note default editor options 2023-01-07 14:47:17 +05:30
StandardNotes CI b839ebb58a chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
2023-01-06 20:16:01 +00:00
Aman Harwara 482c4d1ca4 fix: Fixed issue where the "Attached to" in table view would report an extra number of links 2023-01-07 01:18:50 +05:30
StandardNotes CI 5f96281948 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected].9
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected].1
2023-01-06 16:02:46 +00:00
Aman Harwara 2e79fc412c fix: Fixed issue where the importer would not correctly parse Google Keep JSON notes 2023-01-06 20:57:18 +05:30
StandardNotes CI 5bdbfe9fc7 chore(release): publish
- @standardnotes/[email protected].4
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].8
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected].0
2023-01-06 11:59:51 +00:00
Aman Harwara dd8ccdeadc feat: Added per-tag preference to use table layout and removed "Files Table View" from Labs 2023-01-06 17:00:19 +05:30
StandardNotes CI eea97362f8 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected].7
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
2023-01-05 20:59:57 +00:00
Aman Harwara 01294868c9 Merge branch 'main' of github.com:standardnotes/app 2023-01-06 02:02:16 +05:30
Aman Harwara 77ec9ca335 refactor: files table view -> content table view 2023-01-06 02:02:07 +05:30
StandardNotes CI 3e6c752967 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected].6
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
2023-01-05 18:43:40 +00:00
Aman Harwara ba017d42f5 feat: Added keyboard navigation to Files table view (#2131) 2023-01-05 23:45:10 +05:30
StandardNotes CI bd3df71dd4 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected].5
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
2023-01-05 10:28:19 +00:00
Aman Harwara 22c6e2c56c feat: Added linked items container & autocomplete input to file preview modal 2023-01-05 15:32:18 +05:30
StandardNotes CI 496525ef61 chore(release): publish
- @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected].0
2023-01-04 20:27:27 +00:00
Aman Harwara 6b2f8f3da2 Merge branch 'main' of github.com:standardnotes/app 2023-01-05 01:23:24 +05:30
Aman Harwara e57b28fe29 feat: Added file options menu to file preview modal 2023-01-05 01:23:15 +05:30
Aman Harwara ba4b6a580b feat: Added "Add tag" option to file context menu 2023-01-05 01:16:35 +05:30
Mo 59fc68296b refactor: optimize delay between batches on mobile to allow UI interactivity during load (#2129) 2023-01-04 13:31:45 -06:00
StandardNotes CI 69b2af7612 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected].3
2023-01-04 19:10:43 +00:00
Aman Harwara 30dda73e90 fix: Fixed issue where file upload toast would close before completion if you switched windows 2023-01-05 00:13:42 +05:30
StandardNotes CI 81ea9e896c chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
2023-01-04 01:14:43 +00:00
Mo bc9247df41 chore: trigger build 2023-01-03 18:46:49 -06:00
StandardNotes CI 71e8645ca4 chore(release): publish
- @standardnotes/[email protected].1
 - @standardnotes/[email protected]
2023-01-03 23:51:59 +00:00
Mo 72f384c215 ci: remove mobile dev 2023-01-03 17:26:29 -06:00
Mo b65e8562f2 ci: remove unused workflow 2023-01-03 16:30:16 -06:00
StandardNotes CI 8ff7fb605a chore(release): publish
- @standardnotes/[email protected].2
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected].0
2023-01-03 20:43:29 +00:00
Mo 3c332a35f6 feat: improve initial load performance on mobile (#2126) 2023-01-03 14:15:45 -06:00
Mo a447fa1ad7 test: fix e2e testing setup 2023-01-03 11:00:12 -06:00
Mo 76d2d2112b ci: remove linux ia32 builds
Electron no longer offers builds for this architecture
2023-01-03 10:42:04 -06:00
StandardNotes CI 63cd1f9b07 chore(release): publish
- @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].9
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
2023-01-03 07:12:09 +00:00
Aman Harwara fbc93a4f28 refactor: only show open filesend menu option on mobile 2023-01-03 11:53:44 +05:30
Mo a896b4d9cf chore: remove redunant electronVersion from desktop build params 2023-01-02 23:26:15 -06:00
Mo c0a0ea185c chore(ci): fix mobile version script 2023-01-01 15:28:43 -06:00
StandardNotes CI a3d8f1f3ff chore(release): publish
- @standardnotes/[email protected].2
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
2022-12-29 20:21:46 +00:00
Aman Harwara 6e4bf2417a feat: Added "Import" option in the account menu that allows you to import from plaintext/markdown files, Evernote exports, Simplenote exports, Google Keep exports and also convert Aegis exports to TokenVault notes 2022-12-30 01:22:59 +05:30
StandardNotes CI f1ae7a53ef chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].5
2022-12-29 16:11:00 +00:00
Aman Harwara cd5bd1640c fix: Use regular file list on mobile instead of table view 2022-12-29 21:11:00 +05:30
StandardNotes CI 7508a23979 chore(release): publish
- @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].6
 - @standardnotes/[email protected].4
2022-12-29 15:30:13 +00:00
Karol Sójko 59e8b5c8b5 feat(api): add authenticators api (#2124)
* feat(api): add authenticators api

* fix(services): responses interpreting in authenticator manager
2022-12-29 16:04:53 +01:00
StandardNotes CI 5a8a37413e chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].9
 - @standardnotes/[email protected].8
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].5
 - @standardnotes/[email protected].3
2022-12-29 07:50:08 +00:00
Aman Harwara 113d3bebb4 fix: Fixed issue where Super note font size would shift on first load 2022-12-29 12:51:32 +05:30
Aman Harwara 874f2e90bb Merge branch 'main' of github.com:standardnotes/app 2022-12-29 12:31:59 +05:30
Aman Harwara df4acbb1bc fix: Fixed issue where converting a note to Super from the note options menu would not work 2022-12-29 12:31:50 +05:30
StandardNotes CI b75be1d0f8 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
2022-12-29 05:02:30 +00:00
Mo 015dd1e806 chore: bump version (skip e2e) 2022-12-28 22:47:56 -06:00
Mo 8e3ae80aa0 fix: Fixed issue where Moments could incorrectly get engaged during biometrics unlocking 2022-12-28 22:20:44 -06:00
StandardNotes CI 5a0d87845c chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].8
 - @standardnotes/[email protected].7
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected].0
2022-12-28 21:47:36 +00:00
Aman Harwara b764296c8f feat: Added "Files Table View" to Labs 2022-12-29 02:44:04 +05:30
StandardNotes CI b0c11b1b4d chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
2022-12-28 17:21:41 +00:00
Aman Harwara e81ecfc024 Update CHANGELOG.md 2022-12-28 22:20:28 +05:30
Aman Harwara b408d0a4c5 Update CHANGELOG.md.json 2022-12-28 22:20:08 +05:30
StandardNotes CI 9ec68c9bf6 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
2022-12-28 16:44:26 +00:00
Aman Harwara 2611c690b0 fix: Fixed issue where Moments would capture even after disabling (#2122) 2022-12-28 21:44:01 +05:30
240 changed files with 5171 additions and 3817 deletions
+2 -8
View File
@@ -74,7 +74,7 @@ jobs:
- name: Compile for AppImage
run: yarn run webpack --config desktop.webpack.prod.js
- name: AppImage
run: yarn run electron-builder --linux --x64 --ia32 -c.linux.target=AppImage --publish=never --c.extraMetadata.version=${{ env.APP_VERSION }}
run: yarn run electron-builder --linux --x64 -c.linux.target=AppImage --publish=never --c.extraMetadata.version=${{ env.APP_VERSION }}
- name: AppImageX64
run: yarn run electron-builder --linux --x64 -c.linux.target=AppImage --publish=never --c.extraMetadata.version=${{ env.APP_VERSION }}
- name: AppImageArm64
@@ -83,7 +83,7 @@ jobs:
- name: Deb
run: |
yarn run webpack --config desktop.webpack.prod.js --env deb
yarn run electron-builder --linux --x64 --ia32 -c.linux.target=deb --publish=never --c.extraMetadata.version=${{ env.APP_VERSION }}
yarn run electron-builder --linux --x64 -c.linux.target=deb --publish=never --c.extraMetadata.version=${{ env.APP_VERSION }}
- name: DebArm64
env:
npm_config_target_arch: 'arm64'
@@ -180,12 +180,6 @@ jobs:
- name: Generate Checksums
run: node scripts/sums.mjs
- name: get-npm-version
id: package-version
uses: martinbeentjes/npm-get-version-action@main
with:
path: packages/desktop
- name: Generate Release Notes
uses: ./actions/release-notes
with:
@@ -53,8 +53,3 @@ jobs:
with:
name: assets
path: packages/desktop/dist
- name: get-npm-version
id: package-version
uses: martinbeentjes/npm-get-version-action@main
with:
path: packages/desktop
+2 -8
View File
@@ -43,12 +43,6 @@ jobs:
lane: 'android prod'
subdirectory: 'packages/mobile'
- name: get-npm-version
id: package-version
uses: martinbeentjes/npm-get-version-action@main
with:
path: packages/mobile
- name: Generate Release Notes
uses: ./actions/release-notes
with:
@@ -60,8 +54,8 @@ jobs:
uses: softprops/action-gh-release@v1
with:
token: ${{ secrets.CI_PAT_TOKEN }}
tag_name: "@standardnotes/mobile@${{ steps.package-version.outputs.current-version}}"
name: "Mobile ${{ steps.package-version.outputs.current-version }}"
tag_name: "@standardnotes/mobile@${{ env.PACKAGE_VERSION }}"
name: "Mobile ${{ env.PACKAGE_VERSION }}"
body: ${{ steps.release-notes.outputs.result }}
prerelease: true
draft: false
-102
View File
@@ -1,102 +0,0 @@
name: Mobile TestFlight
on:
push:
tags:
- '*standardnotes/web*'
workflow_dispatch:
jobs:
android:
defaults:
run:
working-directory: packages/mobile
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Export version from package.json
run: |
echo "PACKAGE_VERSION=$(grep '"version"' ../web/package.json | cut -d '"' -f 4 | cut -d "-" -f 1)" >> $GITHUB_ENV
- name: Setup react-native kernel and increase watchers
run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
- name: Decode Dev Android keystore
run: |
echo "${{ secrets.DEV_KEYSTORE }}" > keystore.keystore.asc
gpg -d --passphrase "${{ secrets.DEV_KEYSTORE_PASSPHRASE }}" --batch keystore.keystore.asc > android/app/keystore.keystore
- name: Ruby Setup for Fastlane
uses: ruby/setup-ruby@v1
- name: Install dependencies
run: yarn install --immutable
- run: yarn build:mobile
- name: fastlane
uses: maierj/[email protected]
env:
PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }}
BUILD_NUMBER: ${{ github.run_number }}
ANDROID_KEYSTORE_ALIAS: ${{ secrets.DEV_ANDROID_KEYSTORE_ALIAS }}
ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD: ${{ secrets.DEV_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.DEV_ANDROID_KEYSTORE_PASSWORD }}
GOOGLE_PLAY_JSON_KEY_DATA: ${{ secrets.GOOGLE_PLAY_JSON_KEY_DATA }}
with:
lane: 'android dev'
subdirectory: 'packages/mobile'
- name: get-npm-version
id: package-version
uses: martinbeentjes/npm-get-version-action@main
with:
path: packages/mobile
ios:
env:
ITMSTRANSPORTER_FORCE_ITMS_PACKAGE_UPLOAD: true
defaults:
run:
working-directory: packages/mobile
runs-on: macos-11
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Export version from package.json
run: |
echo "PACKAGE_VERSION=$(grep '"version"' ../web/package.json | cut -d '"' -f 4 | cut -d "-" -f 1)" >> $GITHUB_ENV
- name: Ruby Setup for Fastlane
uses: ruby/setup-ruby@v1
- name: Install dependencies
run: yarn install --immutable && yarn install:pods
- run: yarn build:mobile
- name: Set ssh connection to Github
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Export Apple AppStore Connect API key
run: echo "${{ secrets.APPSTORE_CONNECT_KEY }}" > ios/Authkey.p8
- name: Setup fastlane
uses: maierj/[email protected]
env:
FASTLANE_USER: ${{ secrets.FASTLANE_USER }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
with:
lane: 'ios setup'
subdirectory: 'packages/mobile'
- name: fastlane
uses: maierj/[email protected]
env:
PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }}
APPLE_APP_ID: ${{ secrets.DEV_APP_APPLE_ID }}
APPSTORE_CONNECT_KEY_ID: ${{ secrets.APPSTORE_CONNECT_KEY_ID }}
APPSTORE_CONNECT_KEY_ISSUER_ID: ${{ secrets.APPSTORE_CONNECT_KEY_ISSUER_ID }}
FASTLANE_USER: ${{ secrets.FASTLANE_USER }}
FASTLANE_SESSION: ${{ secrets.FASTLANE_SESSION }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
MATCH_CERTIFICATES_URL: ${{ secrets.MATCH_CERTIFICATES_URL }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }}
MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }}
BUILD_NUMBER: ${{ github.run_number }}
with:
lane: 'ios dev'
subdirectory: 'packages/mobile'
Binary file not shown.
+1 -1
View File
@@ -27,7 +27,7 @@
"build:services": "yarn workspaces foreach -pt --topological-dev --verbose -R --from @standardnotes/services run build",
"build:api": "yarn workspaces foreach -pt --topological-dev --verbose -R --from @standardnotes/api run build",
"start:server:web": "lerna run start --scope=@standardnotes/web",
"start:server:e2e": "lerna run start:test-server --scope=@standardnotes/snjs",
"e2e": "lerna run start:test-server --scope=@standardnotes/snjs",
"reset": "find . -type dir -name node_modules | xargs rm -rf && rm -rf yarn.lock && yarn install",
"release:prod": "lerna version --conventional-commits --yes -m \"chore(release): publish\"",
"publish:prod": "lerna publish from-git --yes --no-verify-access --loglevel verbose",
+36
View File
@@ -3,6 +3,42 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.22.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-09)
### Features
* **snjs:** add sign in with recovery codes use case ([#2130](https://github.com/standardnotes/app/issues/2130)) ([be028ff](https://github.com/standardnotes/app/commit/be028ff87bb5306fc266b70567cbea8a13547e7e))
## [1.21.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/api
## [1.21.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/api
## [1.21.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/api
## [1.21.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/api
# [1.21.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
### Features
* **api:** add authenticators api ([#2124](https://github.com/standardnotes/app/issues/2124)) ([59e8b5c](https://github.com/standardnotes/app/commit/59e8b5c8b5b61ef1cd8f291798c45860736a1296))
## [1.20.26](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/api
## [1.20.25](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/api
## [1.20.24](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-27)
**Note:** Version bump only for package @standardnotes/api
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api",
"version": "1.20.24",
"version": "1.22.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -0,0 +1,5 @@
export enum AuthApiOperations {
GenerateRecoveryCodes,
GetRecoveryKeyParams,
SignInWithRecoveryCodes,
}
@@ -0,0 +1,89 @@
import { ApiVersion } from '../../Api'
import { ApiCallError } from '../../Error/ApiCallError'
import { ErrorMessage } from '../../Error/ErrorMessage'
import {
GenerateRecoveryCodesResponse,
RecoveryKeyParamsResponse,
SignInWithRecoveryCodesResponse,
} from '../../Response'
import { AuthServerInterface } from '../../Server'
import { AuthApiOperations } from './AuthApiOperations'
import { AuthApiServiceInterface } from './AuthApiServiceInterface'
export class AuthApiService implements AuthApiServiceInterface {
private operationsInProgress: Map<AuthApiOperations, boolean>
constructor(private authServer: AuthServerInterface) {
this.operationsInProgress = new Map()
}
async generateRecoveryCodes(): Promise<GenerateRecoveryCodesResponse> {
if (this.operationsInProgress.get(AuthApiOperations.GenerateRecoveryCodes)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}
this.operationsInProgress.set(AuthApiOperations.GenerateRecoveryCodes, true)
try {
const response = await this.authServer.generateRecoveryCodes()
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
} finally {
this.operationsInProgress.set(AuthApiOperations.GenerateRecoveryCodes, false)
}
}
async recoveryKeyParams(dto: {
username: string
codeChallenge: string
recoveryCodes: string
}): Promise<RecoveryKeyParamsResponse> {
if (this.operationsInProgress.get(AuthApiOperations.GetRecoveryKeyParams)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}
this.operationsInProgress.set(AuthApiOperations.GetRecoveryKeyParams, true)
try {
const response = await this.authServer.recoveryKeyParams({
apiVersion: ApiVersion.v0,
...dto,
})
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
} finally {
this.operationsInProgress.set(AuthApiOperations.GetRecoveryKeyParams, false)
}
}
async signInWithRecoveryCodes(dto: {
username: string
password: string
codeVerifier: string
recoveryCodes: string
}): Promise<SignInWithRecoveryCodesResponse> {
if (this.operationsInProgress.get(AuthApiOperations.SignInWithRecoveryCodes)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}
this.operationsInProgress.set(AuthApiOperations.SignInWithRecoveryCodes, true)
try {
const response = await this.authServer.signInWithRecoveryCodes({
apiVersion: ApiVersion.v0,
...dto,
})
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
} finally {
this.operationsInProgress.set(AuthApiOperations.SignInWithRecoveryCodes, false)
}
}
}
@@ -0,0 +1,20 @@
import {
GenerateRecoveryCodesResponse,
RecoveryKeyParamsResponse,
SignInWithRecoveryCodesResponse,
} from '../../Response'
export interface AuthApiServiceInterface {
generateRecoveryCodes(): Promise<GenerateRecoveryCodesResponse>
recoveryKeyParams(dto: {
username: string
codeChallenge: string
recoveryCodes: string
}): Promise<RecoveryKeyParamsResponse>
signInWithRecoveryCodes(dto: {
username: string
password: string
codeVerifier: string
recoveryCodes: string
}): Promise<SignInWithRecoveryCodesResponse>
}
@@ -0,0 +1,8 @@
export enum AuthenticatorApiOperations {
List,
Delete,
GenerateRegistrationOptions,
GenerateAuthenticationOptions,
VerifyRegistrationResponse,
VerifyAuthenticationResponse,
}
@@ -0,0 +1,152 @@
import { ErrorMessage } from '../../Error/ErrorMessage'
import { ApiCallError } from '../../Error/ApiCallError'
import { AuthenticatorApiServiceInterface } from './AuthenticatorApiServiceInterface'
import { AuthenticatorApiOperations } from './AuthenticatorApiOperations'
import {
ListAuthenticatorsResponse,
DeleteAuthenticatorResponse,
GenerateAuthenticatorRegistrationOptionsResponse,
VerifyAuthenticatorRegistrationResponseResponse,
GenerateAuthenticatorAuthenticationOptionsResponse,
VerifyAuthenticatorAuthenticationResponseResponse,
} from '../../Response'
import { AuthenticatorServerInterface } from '../../Server/Authenticator/AuthenticatorServerInterface'
export class AuthenticatorApiService implements AuthenticatorApiServiceInterface {
private operationsInProgress: Map<AuthenticatorApiOperations, boolean>
constructor(private authenticatorServer: AuthenticatorServerInterface) {
this.operationsInProgress = new Map()
}
async list(): Promise<ListAuthenticatorsResponse> {
if (this.operationsInProgress.get(AuthenticatorApiOperations.List)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}
this.operationsInProgress.set(AuthenticatorApiOperations.List, true)
try {
const response = await this.authenticatorServer.list({})
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
} finally {
this.operationsInProgress.set(AuthenticatorApiOperations.List, false)
}
}
async delete(authenticatorId: string): Promise<DeleteAuthenticatorResponse> {
if (this.operationsInProgress.get(AuthenticatorApiOperations.Delete)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}
this.operationsInProgress.set(AuthenticatorApiOperations.Delete, true)
try {
const response = await this.authenticatorServer.delete({
authenticatorId,
})
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
} finally {
this.operationsInProgress.set(AuthenticatorApiOperations.Delete, false)
}
}
async generateRegistrationOptions(
userUuid: string,
username: string,
): Promise<GenerateAuthenticatorRegistrationOptionsResponse> {
if (this.operationsInProgress.get(AuthenticatorApiOperations.GenerateRegistrationOptions)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}
this.operationsInProgress.set(AuthenticatorApiOperations.GenerateRegistrationOptions, true)
try {
const response = await this.authenticatorServer.generateRegistrationOptions({
username,
userUuid,
})
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
} finally {
this.operationsInProgress.set(AuthenticatorApiOperations.GenerateRegistrationOptions, false)
}
}
async verifyRegistrationResponse(
userUuid: string,
name: string,
registrationCredential: Record<string, unknown>,
): Promise<VerifyAuthenticatorRegistrationResponseResponse> {
if (this.operationsInProgress.get(AuthenticatorApiOperations.VerifyRegistrationResponse)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}
this.operationsInProgress.set(AuthenticatorApiOperations.VerifyRegistrationResponse, true)
try {
const response = await this.authenticatorServer.verifyRegistrationResponse({
userUuid,
name,
registrationCredential,
})
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
} finally {
this.operationsInProgress.set(AuthenticatorApiOperations.VerifyRegistrationResponse, false)
}
}
async generateAuthenticationOptions(): Promise<GenerateAuthenticatorAuthenticationOptionsResponse> {
if (this.operationsInProgress.get(AuthenticatorApiOperations.GenerateAuthenticationOptions)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}
this.operationsInProgress.set(AuthenticatorApiOperations.GenerateAuthenticationOptions, true)
try {
const response = await this.authenticatorServer.generateAuthenticationOptions({})
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
} finally {
this.operationsInProgress.set(AuthenticatorApiOperations.GenerateAuthenticationOptions, false)
}
}
async verifyAuthenticationResponse(
userUuid: string,
authenticationCredential: Record<string, unknown>,
): Promise<VerifyAuthenticatorAuthenticationResponseResponse> {
if (this.operationsInProgress.get(AuthenticatorApiOperations.VerifyAuthenticationResponse)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}
this.operationsInProgress.set(AuthenticatorApiOperations.VerifyAuthenticationResponse, true)
try {
const response = await this.authenticatorServer.verifyAuthenticationResponse({
authenticationCredential,
userUuid,
})
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
} finally {
this.operationsInProgress.set(AuthenticatorApiOperations.VerifyAuthenticationResponse, false)
}
}
}
@@ -0,0 +1,27 @@
import {
ListAuthenticatorsResponse,
DeleteAuthenticatorResponse,
GenerateAuthenticatorRegistrationOptionsResponse,
VerifyAuthenticatorRegistrationResponseResponse,
GenerateAuthenticatorAuthenticationOptionsResponse,
VerifyAuthenticatorAuthenticationResponseResponse,
} from '../../Response'
export interface AuthenticatorApiServiceInterface {
list(): Promise<ListAuthenticatorsResponse>
delete(authenticatorId: string): Promise<DeleteAuthenticatorResponse>
generateRegistrationOptions(
userUuid: string,
username: string,
): Promise<GenerateAuthenticatorRegistrationOptionsResponse>
verifyRegistrationResponse(
userUuid: string,
name: string,
registrationCredential: Record<string, unknown>,
): Promise<VerifyAuthenticatorRegistrationResponseResponse>
generateAuthenticationOptions(): Promise<GenerateAuthenticatorAuthenticationOptionsResponse>
verifyAuthenticationResponse(
userUuid: string,
authenticationCredential: Record<string, unknown>,
): Promise<VerifyAuthenticatorAuthenticationResponseResponse>
}
+6
View File
@@ -1,3 +1,9 @@
export * from './Auth/AuthApiOperations'
export * from './Auth/AuthApiService'
export * from './Auth/AuthApiServiceInterface'
export * from './Authenticator/AuthenticatorApiOperations'
export * from './Authenticator/AuthenticatorApiService'
export * from './Authenticator/AuthenticatorApiServiceInterface'
export * from './Subscription/SubscriptionApiOperations'
export * from './Subscription/SubscriptionApiService'
export * from './Subscription/SubscriptionApiServiceInterface'
@@ -1 +1 @@
export type HttpRequestParams = Record<string, unknown>
export type HttpRequestParams = unknown
+2 -2
View File
@@ -276,9 +276,9 @@ export class HttpService implements HttpServiceInterface {
}
private urlForUrlAndParams(url: string, params: HttpRequestParams) {
const keyValueString = Object.keys(params)
const keyValueString = Object.keys(params as Record<string, unknown>)
.map((key) => {
return key + '=' + encodeURIComponent(params[key] as string)
return key + '=' + encodeURIComponent((params as Record<string, unknown>)[key] as string)
})
.join('&')
@@ -0,0 +1,4 @@
export interface DeleteAuthenticatorRequestParams {
authenticatorId: string
[additionalParam: string]: unknown
}
@@ -0,0 +1,3 @@
export interface GenerateAuthenticatorAuthenticationOptionsRequestParams {
[additionalParam: string]: unknown
}
@@ -0,0 +1,5 @@
export interface GenerateAuthenticatorRegistrationOptionsRequestParams {
userUuid: string
username: string
[additionalParam: string]: unknown
}
@@ -0,0 +1,3 @@
export interface ListAuthenticatorsRequestParams {
[additionalParam: string]: unknown
}
@@ -0,0 +1,5 @@
export interface VerifyAuthenticatorAuthenticationResponseRequestParams {
userUuid: string
authenticationCredential: Record<string, unknown>
[additionalParam: string]: unknown
}
@@ -0,0 +1,6 @@
export interface VerifyAuthenticatorRegistrationResponseRequestParams {
userUuid: string
name: string
registrationCredential: Record<string, unknown>
[additionalParam: string]: unknown
}
@@ -0,0 +1,6 @@
export interface RecoveryKeyParamsRequestParams {
apiVersion: string
username: string
codeChallenge: string
recoveryCodes: string
}
@@ -0,0 +1,7 @@
export interface SignInWithRecoveryCodesRequestParams {
apiVersion: string
username: string
password: string
codeVerifier: string
recoveryCodes: string
}
+8
View File
@@ -1,4 +1,12 @@
export * from './ApiEndpointParam'
export * from './Authenticator/DeleteAuthenticatorRequestParams'
export * from './Authenticator/GenerateAuthenticatorAuthenticationOptionsRequestParams'
export * from './Authenticator/GenerateAuthenticatorRegistrationOptionsRequestParams'
export * from './Authenticator/ListAuthenticatorsRequestParams'
export * from './Authenticator/VerifyAuthenticatorAuthenticationResponseRequestParams'
export * from './Authenticator/VerifyAuthenticatorRegistrationResponseRequestParams'
export * from './Recovery/RecoveryKeyParamsRequestParams'
export * from './Recovery/SignInWithRecoveryCodesRequestParams'
export * from './Subscription/AppleIAPConfirmRequestParams'
export * from './Subscription/SubscriptionInviteAcceptRequestParams'
export * from './Subscription/SubscriptionInviteCancelRequestParams'
@@ -0,0 +1,10 @@
import { Either } from '@standardnotes/common'
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
import { HttpResponse } from '../../Http/HttpResponse'
import { DeleteAuthenticatorResponseBody } from './DeleteAuthenticatorResponseBody'
export interface DeleteAuthenticatorResponse extends HttpResponse {
data: Either<DeleteAuthenticatorResponseBody, HttpErrorResponseBody>
}
@@ -0,0 +1,3 @@
export interface DeleteAuthenticatorResponseBody {
message: string
}
@@ -0,0 +1,10 @@
import { Either } from '@standardnotes/common'
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
import { HttpResponse } from '../../Http/HttpResponse'
import { GenerateAuthenticatorAuthenticationOptionsResponseBody } from './GenerateAuthenticatorAuthenticationOptionsResponseBody'
export interface GenerateAuthenticatorAuthenticationOptionsResponse extends HttpResponse {
data: Either<GenerateAuthenticatorAuthenticationOptionsResponseBody, HttpErrorResponseBody>
}
@@ -0,0 +1,3 @@
export interface GenerateAuthenticatorAuthenticationOptionsResponseBody {
options: Record<string, unknown>
}
@@ -0,0 +1,10 @@
import { Either } from '@standardnotes/common'
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
import { HttpResponse } from '../../Http/HttpResponse'
import { GenerateAuthenticatorRegistrationOptionsResponseBody } from './GenerateAuthenticatorRegistrationOptionsResponseBody'
export interface GenerateAuthenticatorRegistrationOptionsResponse extends HttpResponse {
data: Either<GenerateAuthenticatorRegistrationOptionsResponseBody, HttpErrorResponseBody>
}
@@ -0,0 +1,3 @@
export interface GenerateAuthenticatorRegistrationOptionsResponseBody {
options: Record<string, unknown>
}
@@ -0,0 +1,10 @@
import { Either } from '@standardnotes/common'
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
import { HttpResponse } from '../../Http/HttpResponse'
import { ListAuthenticatorsResponseBody } from './ListAuthenticatorsResponseBody'
export interface ListAuthenticatorsResponse extends HttpResponse {
data: Either<ListAuthenticatorsResponseBody, HttpErrorResponseBody>
}
@@ -0,0 +1,6 @@
export interface ListAuthenticatorsResponseBody {
authenticators: Array<{
id: string
name: string
}>
}
@@ -0,0 +1,10 @@
import { Either } from '@standardnotes/common'
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
import { HttpResponse } from '../../Http/HttpResponse'
import { VerifyAuthenticatorAuthenticationResponseResponseBody } from './VerifyAuthenticatorAuthenticationResponseResponseBody'
export interface VerifyAuthenticatorAuthenticationResponseResponse extends HttpResponse {
data: Either<VerifyAuthenticatorAuthenticationResponseResponseBody, HttpErrorResponseBody>
}
@@ -0,0 +1,3 @@
export interface VerifyAuthenticatorAuthenticationResponseResponseBody {
success: boolean
}
@@ -0,0 +1,10 @@
import { Either } from '@standardnotes/common'
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
import { HttpResponse } from '../../Http/HttpResponse'
import { VerifyAuthenticatorRegistrationResponseResponseBody } from './VerifyAuthenticatorRegistrationResponseResponseBody'
export interface VerifyAuthenticatorRegistrationResponseResponse extends HttpResponse {
data: Either<VerifyAuthenticatorRegistrationResponseResponseBody, HttpErrorResponseBody>
}
@@ -0,0 +1,3 @@
export interface VerifyAuthenticatorRegistrationResponseResponseBody {
success: boolean
}
@@ -0,0 +1,10 @@
import { Either } from '@standardnotes/common'
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
import { HttpResponse } from '../../Http/HttpResponse'
import { GenerateRecoveryCodesResponseBody } from './GenerateRecoveryCodesResponseBody'
export interface GenerateRecoveryCodesResponse extends HttpResponse {
data: Either<GenerateRecoveryCodesResponseBody, HttpErrorResponseBody>
}
@@ -0,0 +1,3 @@
export interface GenerateRecoveryCodesResponseBody {
recoveryCodes: string
}
@@ -0,0 +1,10 @@
import { Either } from '@standardnotes/common'
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
import { HttpResponse } from '../../Http/HttpResponse'
import { RecoveryKeyParamsResponseBody } from './RecoveryKeyParamsResponseBody'
export interface RecoveryKeyParamsResponse extends HttpResponse {
data: Either<RecoveryKeyParamsResponseBody, HttpErrorResponseBody>
}
@@ -0,0 +1,5 @@
import { KeyParamsData } from '@standardnotes/responses'
export interface RecoveryKeyParamsResponseBody {
keyParams: KeyParamsData
}
@@ -0,0 +1,10 @@
import { Either } from '@standardnotes/common'
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
import { HttpResponse } from '../../Http/HttpResponse'
import { SignInWithRecoveryCodesResponseBody } from './SignInWithRecoveryCodesResponseBody'
export interface SignInWithRecoveryCodesResponse extends HttpResponse {
data: Either<SignInWithRecoveryCodesResponseBody, HttpErrorResponseBody>
}
@@ -0,0 +1,11 @@
import { KeyParamsData, SessionBody } from '@standardnotes/responses'
export interface SignInWithRecoveryCodesResponseBody {
session: SessionBody
key_params: KeyParamsData
user: {
uuid: string
email: string
protocolVersion: string
}
}
+20
View File
@@ -1,3 +1,23 @@
export * from './Auth/SessionRefreshResponse'
export * from './Auth/SessionRefreshResponseBody'
export * from './Authenticator/DeleteAuthenticatorResponse'
export * from './Authenticator/DeleteAuthenticatorResponseBody'
export * from './Authenticator/GenerateAuthenticatorAuthenticationOptionsResponse'
export * from './Authenticator/GenerateAuthenticatorAuthenticationOptionsResponseBody'
export * from './Authenticator/GenerateAuthenticatorRegistrationOptionsResponse'
export * from './Authenticator/GenerateAuthenticatorRegistrationOptionsResponseBody'
export * from './Authenticator/ListAuthenticatorsResponse'
export * from './Authenticator/ListAuthenticatorsResponseBody'
export * from './Authenticator/VerifyAuthenticatorAuthenticationResponseResponse'
export * from './Authenticator/VerifyAuthenticatorAuthenticationResponseResponseBody'
export * from './Authenticator/VerifyAuthenticatorRegistrationResponseResponse'
export * from './Authenticator/VerifyAuthenticatorRegistrationResponseResponseBody'
export * from './Recovery/GenerateRecoveryCodesResponse'
export * from './Recovery/GenerateRecoveryCodesResponseBody'
export * from './Recovery/RecoveryKeyParamsResponse'
export * from './Recovery/RecoveryKeyParamsResponseBody'
export * from './Recovery/SignInWithRecoveryCodesResponse'
export * from './Recovery/SignInWithRecoveryCodesResponseBody'
export * from './Subscription/AppleIAPConfirmResponse'
export * from './Subscription/AppleIAPConfirmResponseBody'
export * from './Subscription/SubscriptionInviteAcceptResponse'
@@ -0,0 +1,33 @@
import { HttpServiceInterface } from '../../Http/HttpServiceInterface'
import { RecoveryKeyParamsRequestParams, SignInWithRecoveryCodesRequestParams } from '../../Request'
import {
GenerateRecoveryCodesResponse,
RecoveryKeyParamsResponse,
SignInWithRecoveryCodesResponse,
} from '../../Response'
import { AuthServerInterface } from './AuthServerInterface'
import { Paths } from './Paths'
export class AuthServer implements AuthServerInterface {
constructor(private httpService: HttpServiceInterface) {}
async generateRecoveryCodes(): Promise<GenerateRecoveryCodesResponse> {
const response = await this.httpService.post(Paths.v1.generateRecoveryCodes)
return response as GenerateRecoveryCodesResponse
}
async recoveryKeyParams(params: RecoveryKeyParamsRequestParams): Promise<RecoveryKeyParamsResponse> {
const response = await this.httpService.post(Paths.v1.recoveryKeyParams, params)
return response as RecoveryKeyParamsResponse
}
async signInWithRecoveryCodes(
params: SignInWithRecoveryCodesRequestParams,
): Promise<SignInWithRecoveryCodesResponse> {
const response = await this.httpService.post(Paths.v1.signInWithRecoveryCodes, params)
return response as SignInWithRecoveryCodesResponse
}
}
@@ -0,0 +1,12 @@
import { RecoveryKeyParamsRequestParams, SignInWithRecoveryCodesRequestParams } from '../../Request'
import {
GenerateRecoveryCodesResponse,
RecoveryKeyParamsResponse,
SignInWithRecoveryCodesResponse,
} from '../../Response'
export interface AuthServerInterface {
generateRecoveryCodes(): Promise<GenerateRecoveryCodesResponse>
recoveryKeyParams(params: RecoveryKeyParamsRequestParams): Promise<RecoveryKeyParamsResponse>
signInWithRecoveryCodes(params: SignInWithRecoveryCodesRequestParams): Promise<SignInWithRecoveryCodesResponse>
}
@@ -2,8 +2,15 @@ const SessionPaths = {
refreshSession: '/v1/sessions/refresh',
}
const RecoveryPaths = {
generateRecoveryCodes: '/v1/auth/recovery/codes',
recoveryKeyParams: '/v1/auth/recovery/login-params',
signInWithRecoveryCodes: '/v1/auth/recovery/login',
}
export const Paths = {
v1: {
...SessionPaths,
...RecoveryPaths,
},
}
@@ -0,0 +1,67 @@
import { HttpServiceInterface } from '../../Http/HttpServiceInterface'
import {
ListAuthenticatorsRequestParams,
DeleteAuthenticatorRequestParams,
GenerateAuthenticatorRegistrationOptionsRequestParams,
VerifyAuthenticatorRegistrationResponseRequestParams,
GenerateAuthenticatorAuthenticationOptionsRequestParams,
VerifyAuthenticatorAuthenticationResponseRequestParams,
} from '../../Request'
import {
ListAuthenticatorsResponse,
DeleteAuthenticatorResponse,
GenerateAuthenticatorRegistrationOptionsResponse,
VerifyAuthenticatorRegistrationResponseResponse,
GenerateAuthenticatorAuthenticationOptionsResponse,
VerifyAuthenticatorAuthenticationResponseResponse,
} from '../../Response'
import { AuthenticatorServerInterface } from './AuthenticatorServerInterface'
import { Paths } from './Paths'
export class AuthenticatorServer implements AuthenticatorServerInterface {
constructor(private httpService: HttpServiceInterface) {}
async list(params: ListAuthenticatorsRequestParams): Promise<ListAuthenticatorsResponse> {
const response = await this.httpService.get(Paths.v1.listAuthenticators, params)
return response as ListAuthenticatorsResponse
}
async delete(params: DeleteAuthenticatorRequestParams): Promise<DeleteAuthenticatorResponse> {
const response = await this.httpService.delete(Paths.v1.deleteAuthenticator(params.authenticatorId), params)
return response as DeleteAuthenticatorResponse
}
async generateRegistrationOptions(
params: GenerateAuthenticatorRegistrationOptionsRequestParams,
): Promise<GenerateAuthenticatorRegistrationOptionsResponse> {
const response = await this.httpService.get(Paths.v1.generateRegistrationOptions, params)
return response as GenerateAuthenticatorRegistrationOptionsResponse
}
async verifyRegistrationResponse(
params: VerifyAuthenticatorRegistrationResponseRequestParams,
): Promise<VerifyAuthenticatorRegistrationResponseResponse> {
const response = await this.httpService.post(Paths.v1.verifyRegistrationResponse, params)
return response as VerifyAuthenticatorRegistrationResponseResponse
}
async generateAuthenticationOptions(
params: GenerateAuthenticatorAuthenticationOptionsRequestParams,
): Promise<GenerateAuthenticatorAuthenticationOptionsResponse> {
const response = await this.httpService.get(Paths.v1.generateAuthenticationOptions, params)
return response as GenerateAuthenticatorAuthenticationOptionsResponse
}
async verifyAuthenticationResponse(
params: VerifyAuthenticatorAuthenticationResponseRequestParams,
): Promise<VerifyAuthenticatorAuthenticationResponseResponse> {
const response = await this.httpService.post(Paths.v1.verifyAuthenticationResponse, params)
return response as VerifyAuthenticatorAuthenticationResponseResponse
}
}
@@ -0,0 +1,33 @@
import {
ListAuthenticatorsRequestParams,
DeleteAuthenticatorRequestParams,
GenerateAuthenticatorRegistrationOptionsRequestParams,
VerifyAuthenticatorRegistrationResponseRequestParams,
GenerateAuthenticatorAuthenticationOptionsRequestParams,
VerifyAuthenticatorAuthenticationResponseRequestParams,
} from '../../Request'
import {
ListAuthenticatorsResponse,
DeleteAuthenticatorResponse,
GenerateAuthenticatorRegistrationOptionsResponse,
VerifyAuthenticatorRegistrationResponseResponse,
GenerateAuthenticatorAuthenticationOptionsResponse,
VerifyAuthenticatorAuthenticationResponseResponse,
} from '../../Response'
export interface AuthenticatorServerInterface {
list(params: ListAuthenticatorsRequestParams): Promise<ListAuthenticatorsResponse>
delete(params: DeleteAuthenticatorRequestParams): Promise<DeleteAuthenticatorResponse>
generateRegistrationOptions(
params: GenerateAuthenticatorRegistrationOptionsRequestParams,
): Promise<GenerateAuthenticatorRegistrationOptionsResponse>
verifyRegistrationResponse(
params: VerifyAuthenticatorRegistrationResponseRequestParams,
): Promise<VerifyAuthenticatorRegistrationResponseResponse>
generateAuthenticationOptions(
params: GenerateAuthenticatorAuthenticationOptionsRequestParams,
): Promise<GenerateAuthenticatorAuthenticationOptionsResponse>
verifyAuthenticationResponse(
params: VerifyAuthenticatorAuthenticationResponseRequestParams,
): Promise<VerifyAuthenticatorAuthenticationResponseResponse>
}
@@ -0,0 +1,14 @@
const AuthenticatorPaths = {
listAuthenticators: '/v1/authenticators',
deleteAuthenticator: (authenticatorId: string) => `/v1/authenticators/${authenticatorId}`,
generateRegistrationOptions: '/v1/authenticators/generate-registration-options',
verifyRegistrationResponse: '/v1/authenticators/verify-registration',
generateAuthenticationOptions: '/v1/authenticators/generate-authentication-options',
verifyAuthenticationResponse: '/v1/authenticators/verify-authentication',
}
export const Paths = {
v1: {
...AuthenticatorPaths,
},
}
+4
View File
@@ -1,3 +1,7 @@
export * from './Auth/AuthServer'
export * from './Auth/AuthServerInterface'
export * from './Authenticator/AuthenticatorServer'
export * from './Authenticator/AuthenticatorServerInterface'
export * from './Subscription/SubscriptionServer'
export * from './Subscription/SubscriptionServerInterface'
export * from './User/UserServer'
+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.12.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/blocks-editor
## [1.12.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-26)
**Note:** Version bump only for package @standardnotes/blocks-editor
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/blocks-editor",
"version": "1.12.1",
"version": "1.12.2",
"private": true,
"main": "./src/index.ts",
"scripts": {
+84
View File
@@ -3,6 +3,90 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.104.76](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-09)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.75](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-07)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.74](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.73](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.72](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.71](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-05)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.70](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-05)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.69](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-05)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.68](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.67](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.66](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.65](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.63](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.62](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.61](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.60](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.59](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.58](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.57](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.56](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.55](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/desktop
## [3.104.54](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-27)
**Note:** Version bump only for package @standardnotes/desktop
+1 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@standardnotes/desktop",
"main": "./app/dist/index.js",
"version": "3.104.54",
"version": "3.104.76",
"license": "AGPL-3.0-or-later",
"author": "Standard Notes.",
"private": true,
@@ -80,7 +80,6 @@
"webpack-merge": "^5.8.0"
},
"build": {
"electronVersion": "17.4.2",
"appId": "org.standardnotes.standardnotes",
"artifactName": "standard-notes-${version}-${os}-${arch}.${ext}",
"afterSign": "scripts/notarizeMac.js",
+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.
## [0.2.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/docs
## [0.2.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
### Bug Fixes
+1 -1
View File
@@ -178,7 +178,7 @@ Due to mounted volumes, we recommend running the setup as a root user. If you wi
1. Once the server has finished rebooting, log back into the server and start the Standard Notes server process:
```shell
cd standalone
cd self-hosted
./server.sh start
```
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/docs",
"version": "0.2.5",
"version": "0.2.6",
"license": "AGPL-3.0-or-later",
"author": "Standard Notes.",
"private": true,
+30
View File
@@ -3,6 +3,36 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.20.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-09)
### Features
* **snjs:** add sign in with recovery codes use case ([#2130](https://github.com/standardnotes/app/issues/2130)) ([be028ff](https://github.com/standardnotes/app/commit/be028ff87bb5306fc266b70567cbea8a13547e7e))
## [1.19.35](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/encryption
## [1.19.34](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/encryption
## [1.19.33](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/encryption
## [1.19.32](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/encryption
## [1.19.31](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/encryption
## [1.19.30](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/encryption
## [1.19.29](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-27)
**Note:** Version bump only for package @standardnotes/encryption
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/encryption",
"version": "1.19.29",
"version": "1.20.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -32,6 +32,9 @@ export interface EncryptionProviderInterface {
getKeyEmbeddedKeyParams(key: EncryptedPayloadInterface): SNRootKeyParams | undefined
computeRootKey(password: string, keyParams: SNRootKeyParams): Promise<RootKeyInterface>
supportedVersions(): ProtocolVersion[]
isVersionNewerThanLibraryVersion(version: ProtocolVersion): boolean
platformSupportsKeyDerivation(keyParams: SNRootKeyParams): boolean
computeWrappingKey(passcode: string): Promise<RootKeyInterface>
getUserVersion(): ProtocolVersion | undefined
decryptBackupFile(
file: BackupFile,
+16
View File
@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.58.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
### Features
* Added per-tag preference to use table layout and removed "Files Table View" from Labs ([dd8ccde](https://github.com/standardnotes/app/commit/dd8ccdeadc6c2fd7f7ccd66f2dc4b0081616fb2b))
## [1.57.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/features
# [1.57.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
### Features
* Added "Files Table View" to Labs ([b764296](https://github.com/standardnotes/app/commit/b764296c8f831d06f854dcf2982e644c27e14e7c))
# [1.56.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-05)
### Features
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/features",
"version": "1.56.0",
"version": "1.58.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+30
View File
@@ -3,6 +3,36 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.28.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-09)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.28.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.28.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/filepicker
# [1.28.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
### Features
* improve initial load performance on mobile ([#2126](https://github.com/standardnotes/app/issues/2126)) ([3c332a3](https://github.com/standardnotes/app/commit/3c332a35f6024c46020a1d6ac68a5df989804142))
## [1.27.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.27.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.27.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.27.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-27)
**Note:** Version bump only for package @standardnotes/filepicker
@@ -18,17 +18,6 @@ export default class WebDeviceInterface {
}
}
async getAllRawStorageKeyValues() {
const results = []
for (const key of Object.keys(localStorage)) {
results.push({
key: key,
value: localStorage[key],
})
}
return results
}
async setRawStorageValue(key, value) {
localStorage.setItem(key, value)
}
@@ -57,7 +46,7 @@ export default class WebDeviceInterface {
return `${this._getDatabaseKeyPrefix(identifier)}${id}`
}
async getAllRawDatabasePayloads(identifier) {
async getAllDatabaseEntries(identifier) {
const models = []
for (const key in localStorage) {
if (key.startsWith(this._getDatabaseKeyPrefix(identifier))) {
@@ -67,21 +56,21 @@ export default class WebDeviceInterface {
return models
}
async saveRawDatabasePayload(payload, identifier) {
async saveDatabaseEntry(payload, identifier) {
localStorage.setItem(this._keyForPayloadId(payload.uuid, identifier), JSON.stringify(payload))
}
async saveRawDatabasePayloads(payloads, identifier) {
async saveDatabaseEntries(payloads, identifier) {
for (const payload of payloads) {
await this.saveRawDatabasePayload(payload, identifier)
await this.saveDatabaseEntry(payload, identifier)
}
}
async removeRawDatabasePayloadWithId(id, identifier) {
async removeDatabaseEntry(id, identifier) {
localStorage.removeItem(this._keyForPayloadId(id, identifier))
}
async removeAllRawDatabasePayloads(identifier) {
async removeAllDatabaseEntries(identifier) {
for (const key in localStorage) {
if (key.startsWith(this._getDatabaseKeyPrefix(identifier))) {
delete localStorage[key]
@@ -121,12 +110,6 @@ export default class WebDeviceInterface {
localStorage.setItem(KEYCHAIN_STORAGE_KEY, JSON.stringify(keychain))
}
/** Allows unit tests to set legacy keychain structure as it was <= 003 */
// eslint-disable-next-line camelcase
async setLegacyRawKeychainValue(value) {
localStorage.setItem(KEYCHAIN_STORAGE_KEY, JSON.stringify(value))
}
async getRawKeychainValue() {
const keychain = localStorage.getItem(KEYCHAIN_STORAGE_KEY)
return JSON.parse(keychain)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/filepicker",
"version": "1.27.7",
"version": "1.28.3",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+28
View File
@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.14.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-09)
**Note:** Version bump only for package @standardnotes/files
## [1.14.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/files
## [1.14.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/files
## [1.14.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/files
## [1.14.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/files
## [1.14.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/files
## [1.14.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/files
## [1.14.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-27)
**Note:** Version bump only for package @standardnotes/files
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files",
"version": "1.14.6",
"version": "1.14.13",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.8.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
### Features
* Added "Import" option in the account menu that allows you to import from plaintext/markdown files, Evernote exports, Simplenote exports, Google Keep exports and also convert Aegis exports to TokenVault notes ([6e4bf24](https://github.com/standardnotes/app/commit/6e4bf2417abbd88cbac1fd34ae8306041fa2279f))
# [1.7.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-07)
### Features
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/icons",
"version": "1.7.0",
"version": "1.8.0",
"private": true,
"main": "dist/index.js",
"types": "dist/index.d.ts",
+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" viewBox="0 0 48 48">
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
d="M19.59 40a2.4 2.4 0 0 1-3.28-.88l-.48-.82A2.4 2.4 0 0 1 20 35.91l.48.82a2.42 2.42 0 0 1-.89 3.27Zm10.85 0a2.4 2.4 0 0 1-3.28-.88l-5.64-9.76A2.4 2.4 0 1 1 25.68 27l5.64 9.77a2.39 2.39 0 0 1-.88 3.23Zm10.86 0a2.42 2.42 0 0 1-3.3-.86L25.67 17.75a1.92 1.92 0 0 0-3.33 0L10 39.14a2.42 2.42 0 0 1-2.09 1.2A2.37 2.37 0 0 1 6.7 40a2.4 2.4 0 0 1-.88-3.28l16.1-27.86a2.4 2.4 0 0 1 4.16 0l16.1 27.88A2.4 2.4 0 0 1 41.3 40Z" />
</svg>

After

Width:  |  Height:  |  Size: 612 B

+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path fill="currentColor"
d="M15.09 11.63s.19-1.28.91-1.28c.76 0 1.78 1.71 1.78 1.71s-2.32-.43-2.69-.43M19 4.69c-.36-.6-2.17-1.28-3.11-1.28H13.5S12.7 2 10.88 2c-1.83 0-1.71.81-1.71 1.5v2.82l-.83.87H4.5s-1.06.72-1.06 2.25c0 1.56.48 6.91 3.69 7.41c3.8.58 4.45-1.18 4.45-1.39c0-.9.02-2.25.02-2.25s1.11 2.12 2.79 2.12s2.65.97 2.65 1.96v1.84S17 20.28 16 20.28h-2.11s-.69-.54-.69-1.28c0-.75.33-.95.73-.95c.39 0 .72.04.72.04v-1.56s-3.18-.03-3.18 2.41c0 2.43 1.66 3.06 2.99 3.06h2.17s3.93-.5 3.93-8.25S19.33 5.28 19 4.69M7.5 6.31H4.26l4.06-4.09V5.5l-.82.81Z" />
</svg>

After

Width:  |  Height:  |  Size: 660 B

+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path fill="currentColor"
d="M4 2h16a2 2 0 0 1 2 2v13.33L17.33 22H4a2 2 0 0 1-2-2V4c0-1.1.9-2 2-2m13 15v3.25L20.25 17H17m-7 2h4v-1h1v-5a5.002 5.002 0 0 0-3-9a5.002 5.002 0 0 0-3 9v5h1v1m4-2h-4v-2h4v2M12 5c2.21 0 4 1.79 4 4c0 1.5-.8 2.77-2 3.46V14h-4v-1.54C8.8 11.77 8 10.5 8 9c0-2.21 1.79-4 4-4Z" />
</svg>

After

Width:  |  Height:  |  Size: 406 B

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path fill="currentColor"
d="M3.466 3.62c-.004.052-.014.104-.018.158c-.406 4.626 2.747 8.548 8.03 9.994c2.024.553 5.374 2.018 5.06 5.599a5.063 5.063 0 0 1-1.803 3.46c-1.022.857-2.308 1.21-3.64 1.166C5.147 23.794 0 18.367 0 12.05a11.95 11.95 0 0 1 3.467-8.428zM9.82 1.032C10.727.27 11.876-.046 13.055.005C18.996.27 24 5.67 24 11.936a11.94 11.94 0 0 1-2.667 7.536c.332-4.908-2.94-8.897-8.59-10.441c-2.337-.64-4.749-2.274-4.514-4.948A4.467 4.467 0 0 1 9.82 1.03z" />
</svg>

After

Width:  |  Height:  |  Size: 570 B

+8
View File
@@ -201,6 +201,10 @@ import UserSwitch from './ic-user-switch.svg'
import ViewIcon from './ic-view.svg'
import WarningIcon from './ic-warning.svg'
import WindowIcon from './ic-window.svg'
import EvernoteIcon from './ic-evernote.svg'
import GoogleKeepIcon from './ic-gkeep.svg'
import SimplenoteIcon from './ic-simplenote.svg'
import AegisIcon from './ic-aegis.svg'
export {
AccessibilityIcon,
@@ -406,4 +410,8 @@ export {
ViewIcon,
WarningIcon,
WindowIcon,
EvernoteIcon,
GoogleKeepIcon,
SimplenoteIcon,
AegisIcon,
}
+90
View File
@@ -3,6 +3,96 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.50.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-09)
**Note:** Version bump only for package @standardnotes/mobile
## [3.50.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-07)
**Note:** Version bump only for package @standardnotes/mobile
## [3.50.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/mobile
## [3.50.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/mobile
## [3.50.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/mobile
## [3.50.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-05)
**Note:** Version bump only for package @standardnotes/mobile
## [3.50.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-05)
**Note:** Version bump only for package @standardnotes/mobile
## [3.50.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-05)
**Note:** Version bump only for package @standardnotes/mobile
## [3.50.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/mobile
## [3.50.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/mobile
## [3.50.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/mobile
## [3.50.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/mobile
# [3.50.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
### Features
* improve initial load performance on mobile ([#2126](https://github.com/standardnotes/app/issues/2126)) ([3c332a3](https://github.com/standardnotes/app/commit/3c332a35f6024c46020a1d6ac68a5df989804142))
## [3.49.60](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/mobile
## [3.49.59](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/mobile
## [3.49.58](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/mobile
## [3.49.57](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/mobile
## [3.49.56](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/mobile
## [3.49.55](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/mobile
## [3.49.54](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/mobile
## [3.49.53](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/mobile
## [3.49.52](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/mobile
## [3.49.51](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-27)
**Note:** Version bump only for package @standardnotes/mobile
-6
View File
@@ -1,16 +1,10 @@
for_platform :ios do
for_lane :dev do
app_identifier "com.standardnotes.standardnotes.dev"
end
for_lane :prod do
app_identifier "com.standardnotes.standardnotes"
end
end
for_platform :android do
for_lane :dev do
package_name 'com.standardnotes.dev'
end
for_lane :prod do
package_name 'com.standardnotes'
end
+1 -1
View File
@@ -2,7 +2,7 @@ storage_mode("git")
# type("development") # The default type, can be: appstore, adhoc, enterprise or development
app_identifier(["com.standardnotes.standardnotes", "com.standardnotes.standardnotes.dev"])
app_identifier(["com.standardnotes.standardnotes"])
# For all available options run `fastlane match --help`
# Remove the # in the beginning of the line to enable the other options
+16 -2
View File
@@ -75,6 +75,9 @@ PODS:
- glog (0.3.5)
- hermes-engine (0.70.6)
- libevent (2.1.12)
- MMKV (1.2.14):
- MMKVCore (~> 1.2.14)
- MMKVCore (1.2.14)
- OpenSSL-Universal (1.1.1100)
- RCT-Folly (2021.07.22.00):
- boost
@@ -304,6 +307,9 @@ PODS:
- glog
- react-native-fingerprint-scanner (5.0.0):
- React-Core
- react-native-mmkv (2.5.1):
- MMKV (>= 1.2.13)
- React-Core
- react-native-version-info (1.1.1):
- React-Core
- react-native-webview (11.23.1):
@@ -444,6 +450,7 @@ DEPENDENCIES:
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- react-native-fingerprint-scanner (from `../node_modules/react-native-fingerprint-scanner`)
- react-native-mmkv (from `../node_modules/react-native-mmkv`)
- react-native-version-info (from `../node_modules/react-native-version-info`)
- react-native-webview (from `../node_modules/react-native-webview`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
@@ -483,6 +490,8 @@ SPEC REPOS:
- FlipperKit
- fmt
- libevent
- MMKV
- MMKVCore
- OpenSSL-Universal
- SocketRocket
- TrustKit
@@ -533,6 +542,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/logger"
react-native-fingerprint-scanner:
:path: "../node_modules/react-native-fingerprint-scanner"
react-native-mmkv:
:path: "../node_modules/react-native-mmkv"
react-native-version-info:
:path: "../node_modules/react-native-version-info"
react-native-webview:
@@ -583,7 +594,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
boost: a7c83b31436843459a1961bfd74b96033dc77234
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
FBLazyVector: 48289402952f4f7a4e235de70a9a590aa0b79ef4
FBReactNativeSpec: dd1186fd05255e3457baa2f4ca65e94c2cd1e3ac
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
@@ -596,9 +607,11 @@ SPEC CHECKSUMS:
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 85ecdd10ee8d8ec362ef519a6a45ff9aa27b2e85
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: 2af7b7a59128f250adfd86f15aa1d5a2ecd39995
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
MMKV: 9c4663aa7ca255d478ff10f2f5cb7d17c1651ccd
MMKVCore: 89f5c8a66bba2dcd551779dea4d412eeec8ff5bb
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda
RCTRequired: e1866f61af7049eb3d8e08e8b133abd38bc1ca7a
@@ -616,6 +629,7 @@ SPEC CHECKSUMS:
React-jsinspector: 60769e5a0a6d4b32294a2456077f59d0266f9a8b
React-logger: 1623c216abaa88974afce404dc8f479406bbc3a0
react-native-fingerprint-scanner: be63e626b31fb951780a5fac5328b065a61a3d6e
react-native-mmkv: 69b9c003f10afdd01addf7c6ee784ce42ee2eff3
react-native-version-info: a106f23009ac0db4ee00de39574eb546682579b9
react-native-webview: d33e2db8925d090871ffeb232dfa50cb3a727581
React-perflogger: 8c79399b0500a30ee8152d0f9f11beae7fc36595
+3 -1
View File
@@ -100,7 +100,7 @@
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library is optionally used to select files to upload or QR code images from your photo library.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone is optionally used to capture videos.</string>
<string>Microphone is optionally used to capture videos.</string>
<key>UIAppFonts</key>
<array>
<string>AntDesign.ttf</string>
@@ -147,5 +147,7 @@
<false/>
<key>supportsAlternateIcons</key>
<true/>
<key>RCTAsyncStorageExcludeFromBackup</key>
<false/>
</dict>
</plist>
+2 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/mobile",
"version": "3.49.51",
"version": "3.50.12",
"author": "Standard Notes.",
"private": true,
"license": "AGPL-3.0-or-later",
@@ -59,6 +59,7 @@
"react-native-fs": "^2.20.0",
"react-native-iap": "^12.4.4",
"react-native-keychain": "standardnotes/react-native-keychain#d277d360494cbd02be4accb4a360772a8e0e97b6",
"react-native-mmkv": "^2.5.1",
"react-native-privacy-snapshot": "standardnotes/react-native-privacy-snapshot#653e904c90fc6f2b578da59138f2bfe5d7f942fe",
"react-native-share": "^8.0.0",
"react-native-version-info": "^1.1.1",
@@ -0,0 +1,158 @@
import AsyncStorage from '@react-native-community/async-storage'
import {
DatabaseKeysLoadChunk,
DatabaseKeysLoadChunkResponse,
DatabaseLoadOptions,
GetSortedPayloadsByPriority,
TransferPayload,
} from '@standardnotes/snjs'
import { Platform } from 'react-native'
import { DatabaseInterface } from './DatabaseInterface'
import { DatabaseMetadata } from './DatabaseMetadata'
import { FlashKeyValueStore } from './FlashKeyValueStore'
import { isLegacyIdentifier } from './LegacyIdentifier'
import { showLoadFailForItemIds } from './showLoadFailForItemIds'
export class Database implements DatabaseInterface {
private metadataStore: DatabaseMetadata
constructor(private identifier: string) {
const flashStorage = new FlashKeyValueStore(identifier)
this.metadataStore = new DatabaseMetadata(identifier, flashStorage)
}
private databaseKeyForPayloadId(id: string) {
return `${this.getDatabaseKeyPrefix()}${id}`
}
private getDatabaseKeyPrefix() {
if (this.identifier && !isLegacyIdentifier(this.identifier)) {
return `${this.identifier}-Item-`
} else {
return 'Item-'
}
}
async getAllEntries<T extends TransferPayload = TransferPayload>(): Promise<T[]> {
const keys = await this.getAllKeys()
return this.multiGet(keys)
}
async getAllKeys(): Promise<string[]> {
const keys = await AsyncStorage.getAllKeys()
const filtered = keys.filter((key) => {
return key.startsWith(this.getDatabaseKeyPrefix())
})
return filtered
}
async multiDelete(keys: string[]): Promise<void> {
return AsyncStorage.multiRemove(keys)
}
async deleteItem(itemUuid: string): Promise<void> {
const key = this.databaseKeyForPayloadId(itemUuid)
this.metadataStore.deleteMetadataItem(itemUuid)
return this.multiDelete([key])
}
async deleteAll(): Promise<void> {
const keys = await this.getAllKeys()
return this.multiDelete(keys)
}
async setItems(items: TransferPayload[]): Promise<void> {
if (items.length === 0) {
return
}
await Promise.all(
items.map((item) => {
return Promise.all([
AsyncStorage.setItem(this.databaseKeyForPayloadId(item.uuid), JSON.stringify(item)),
this.metadataStore.setMetadataForPayloads([item]),
])
}),
)
}
async getLoadChunks(options: DatabaseLoadOptions): Promise<DatabaseKeysLoadChunkResponse> {
let metadataItems = this.metadataStore.getAllMetadataItems()
if (metadataItems.length === 0) {
const allEntries = await this.getAllEntries()
metadataItems = this.metadataStore.runMigration(allEntries)
}
const sorted = GetSortedPayloadsByPriority(metadataItems, options)
const itemsKeysChunk: DatabaseKeysLoadChunk = {
keys: sorted.itemsKeyPayloads.map((item) => this.databaseKeyForPayloadId(item.uuid)),
}
const contentTypePriorityChunk: DatabaseKeysLoadChunk = {
keys: sorted.contentTypePriorityPayloads.map((item) => this.databaseKeyForPayloadId(item.uuid)),
}
const remainingKeys = sorted.remainingPayloads.map((item) => this.databaseKeyForPayloadId(item.uuid))
const remainingKeysChunks: DatabaseKeysLoadChunk[] = []
for (let i = 0; i < remainingKeys.length; i += options.batchSize) {
remainingKeysChunks.push({
keys: remainingKeys.slice(i, i + options.batchSize),
})
}
const result: DatabaseKeysLoadChunkResponse = {
keys: {
itemsKeys: itemsKeysChunk,
remainingChunks: [contentTypePriorityChunk, ...remainingKeysChunks],
},
remainingChunksItemCount: sorted.contentTypePriorityPayloads.length + sorted.remainingPayloads.length,
}
return result
}
async multiGet<T>(keys: string[]): Promise<T[]> {
const results: T[] = []
if (Platform.OS === 'android') {
const failedItemIds: string[] = []
for (const key of keys) {
try {
const item = await AsyncStorage.getItem(key)
if (item) {
try {
results.push(JSON.parse(item) as T)
} catch (e) {
results.push(item as T)
}
}
} catch (e) {
console.error('Error getting item', key, e)
failedItemIds.push(key)
}
}
if (failedItemIds.length > 0) {
showLoadFailForItemIds(failedItemIds)
}
} else {
try {
for (const item of await AsyncStorage.multiGet(keys)) {
if (item[1]) {
try {
results.push(JSON.parse(item[1]))
} catch (e) {
results.push(item[1] as T)
}
}
}
} catch (e) {
console.error('Error getting items', e)
}
}
return results
}
}
@@ -0,0 +1,10 @@
import { TransferPayload } from '@standardnotes/snjs'
export interface DatabaseInterface {
getAllKeys(): Promise<string[]>
multiDelete(keys: string[]): Promise<void>
deleteItem(itemUuid: string): Promise<void>
deleteAll(): Promise<void>
setItems(items: TransferPayload[]): Promise<void>
multiGet<T>(keys: string[]): Promise<T[]>
}
@@ -0,0 +1,39 @@
import { DatabaseItemMetadata, isNotUndefined, TransferPayload } from '@standardnotes/snjs'
import { FlashKeyValueStore } from './FlashKeyValueStore'
export class DatabaseMetadata {
constructor(private identifier: string, private flashStorage: FlashKeyValueStore) {}
runMigration(payloads: TransferPayload[]) {
const metadataItems = this.setMetadataForPayloads(payloads)
return metadataItems
}
setMetadataForPayloads(payloads: TransferPayload[]) {
const metadataItems = []
for (const payload of payloads) {
const { uuid, content_type, updated_at } = payload
const key = this.keyForUuid(uuid)
const metadata: DatabaseItemMetadata = { uuid, content_type, updated_at }
this.flashStorage.set(key, metadata)
metadataItems.push(metadata)
}
return metadataItems
}
deleteMetadataItem(itemUuid: string) {
const key = this.keyForUuid(itemUuid)
this.flashStorage.delete(key)
}
getAllMetadataItems(): DatabaseItemMetadata[] {
const keys = this.flashStorage.getAllKeys()
const metadataKeys = keys.filter((key) => key.endsWith('-Metadata'))
const metadataItems = this.flashStorage.multiGet<DatabaseItemMetadata>(metadataKeys).filter(isNotUndefined)
return metadataItems
}
private keyForUuid(uuid: string) {
return `${this.identifier}-Item-${uuid}-Metadata`
}
}
@@ -0,0 +1,40 @@
import { MMKV } from 'react-native-mmkv'
export class FlashKeyValueStore {
private storage: MMKV
constructor(identifier: string) {
this.storage = new MMKV({ id: identifier })
}
set(key: string, value: unknown): void {
this.storage.set(key, JSON.stringify(value))
}
delete(key: string): void {
this.storage.delete(key)
}
deleteAll(): void {
this.storage.clearAll()
}
getAllKeys(): string[] {
return this.storage.getAllKeys()
}
get<T>(key: string): T | undefined {
const item = this.storage.getString(key)
if (item) {
try {
return JSON.parse(item)
} catch (e) {
return item as T
}
}
}
multiGet<T>(keys: string[]): (T | undefined)[] {
return keys.map((key) => this.get<T>(key))
}
}
@@ -0,0 +1,15 @@
import { ApplicationIdentifier } from '@standardnotes/snjs'
/**
* This identifier was the database name used in Standard Notes web/desktop.
*/
const LEGACY_IDENTIFIER = 'standardnotes'
/**
* We use this function to decide if we need to prefix the identifier in getDatabaseKeyPrefix or not.
* It is also used to decide if the raw or the namespaced keychain is used.
* @param identifier The ApplicationIdentifier
*/
export const isLegacyIdentifier = function (identifier: ApplicationIdentifier) {
return identifier && identifier === LEGACY_IDENTIFIER
}
@@ -0,0 +1,26 @@
import AsyncStorage from '@react-native-community/async-storage'
export class LegacyKeyValueStore {
set(key: string, value: string): Promise<void> {
return AsyncStorage.setItem(key, JSON.stringify(value))
}
delete(key: string): Promise<void> {
return AsyncStorage.removeItem(key)
}
deleteAll(): Promise<void> {
return AsyncStorage.clear()
}
async getValue<T>(key: string): Promise<T | undefined> {
const item = await AsyncStorage.getItem(key)
if (item) {
try {
return JSON.parse(item)
} catch (e) {
return item as T
}
}
}
}
@@ -0,0 +1,16 @@
import { Alert } from 'react-native'
export const showLoadFailForItemIds = (failedItemIds: string[]) => {
let text =
'The following items could not be loaded. This may happen if you are in low-memory conditions, or if the note is very large in size. We recommend breaking up large notes into smaller chunks using the desktop or web app.\n\nItems:\n'
let index = 0
text += failedItemIds.map((id) => {
let result = id
if (index !== failedItemIds.length - 1) {
result += '\n'
}
index++
return result
})
Alert.alert('Unable to load item(s)', text)
}
@@ -1,12 +1,11 @@
import AsyncStorage from '@react-native-community/async-storage'
import SNReactNative from '@standardnotes/react-native-utils'
import { AppleIAPReceipt } from '@standardnotes/services'
import {
AppleIAPProductId,
AppleIAPReceipt,
ApplicationIdentifier,
DatabaseKeysLoadChunkResponse,
DatabaseLoadOptions,
Environment,
LegacyMobileKeychainStructure,
LegacyRawKeychainValue,
MobileDeviceInterface,
NamespacedRootKeyInKeychain,
Platform as SNPlatform,
@@ -41,8 +40,11 @@ import {
import { hide, show } from 'react-native-privacy-snapshot'
import Share from 'react-native-share'
import { AndroidBackHandlerService } from '../AndroidBackHandlerService'
import { AppStateObserverService } from '../AppStateObserverService'
import { PurchaseManager } from '../PurchaseManager'
import { AppStateObserverService } from './../AppStateObserverService'
import { Database } from './Database/Database'
import { isLegacyIdentifier } from './Database/LegacyIdentifier'
import { LegacyKeyValueStore } from './Database/LegacyKeyValueStore'
import Keychain from './Keychain'
export type BiometricsType = 'Fingerprint' | 'Face ID' | 'Biometrics' | 'Touch ID'
@@ -53,41 +55,6 @@ export enum MobileDeviceEvent {
type MobileDeviceEventHandler = (event: MobileDeviceEvent) => void
/**
* This identifier was the database name used in Standard Notes web/desktop.
*/
const LEGACY_IDENTIFIER = 'standardnotes'
/**
* We use this function to decide if we need to prefix the identifier in getDatabaseKeyPrefix or not.
* It is also used to decide if the raw or the namespaced keychain is used.
* @param identifier The ApplicationIdentifier
*/
const isLegacyIdentifier = function (identifier: ApplicationIdentifier) {
return identifier && identifier === LEGACY_IDENTIFIER
}
function isLegacyMobileKeychain(
x: LegacyMobileKeychainStructure | RawKeychainValue,
): x is LegacyMobileKeychainStructure {
return x.ak != undefined
}
const showLoadFailForItemIds = (failedItemIds: string[]) => {
let text =
'The following items could not be loaded. This may happen if you are in low-memory conditions, or if the note is very large in size. We recommend breaking up large notes into smaller chunks using the desktop or web app.\n\nItems:\n'
let index = 0
text += failedItemIds.map((id) => {
let result = id
if (index !== failedItemIds.length - 1) {
result += '\n'
}
index++
return result
})
Alert.alert('Unable to load item(s)', text)
}
export class MobileDevice implements MobileDeviceInterface {
environment: Environment.Mobile = Environment.Mobile
platform: SNPlatform.Ios | SNPlatform.Android = Platform.OS === 'ios' ? SNPlatform.Ios : SNPlatform.Android
@@ -95,6 +62,8 @@ export class MobileDevice implements MobileDeviceInterface {
public isDarkMode = false
public statusBarBgColor: string | undefined
private componentUrls: Map<UuidString, string> = new Map()
private keyValueStore = new LegacyKeyValueStore()
private databases = new Map<string, Database>()
constructor(
private stateObserverService?: AppStateObserverService,
@@ -106,6 +75,17 @@ export class MobileDevice implements MobileDeviceInterface {
return PurchaseManager.getInstance().purchase(plan)
}
private findOrCreateDatabase(identifier: ApplicationIdentifier): Database {
const existing = this.databases.get(identifier)
if (existing) {
return existing
}
const newDb = new Database(identifier)
this.databases.set(identifier, newDb)
return newDb
}
deinit() {
this.stateObserverService?.deinit()
;(this.stateObserverService as unknown) = undefined
@@ -120,10 +100,6 @@ export class MobileDevice implements MobileDeviceInterface {
console.log(args)
}
async setLegacyRawKeychainValue(value: LegacyRawKeychainValue): Promise<void> {
await Keychain.setKeys(value)
}
public async getJsonParsedRawStorageValue(key: string): Promise<unknown | undefined> {
const value = await this.getRawStorageValue(key)
if (value == undefined) {
@@ -136,219 +112,57 @@ export class MobileDevice implements MobileDeviceInterface {
}
}
private getDatabaseKeyPrefix(identifier: ApplicationIdentifier) {
if (identifier && !isLegacyIdentifier(identifier)) {
return `${identifier}-Item-`
} else {
return 'Item-'
}
}
private keyForPayloadId(id: string, identifier: ApplicationIdentifier) {
return `${this.getDatabaseKeyPrefix(identifier)}${id}`
}
private async getAllDatabaseKeys(identifier: ApplicationIdentifier) {
const keys = await AsyncStorage.getAllKeys()
const filtered = keys.filter((key) => {
return key.startsWith(this.getDatabaseKeyPrefix(identifier))
})
return filtered
}
getDatabaseKeys(): Promise<string[]> {
return AsyncStorage.getAllKeys()
}
private async getRawStorageKeyValues(keys: string[]) {
const results: { key: string; value: unknown }[] = []
if (Platform.OS === 'android') {
for (const key of keys) {
try {
const item = await AsyncStorage.getItem(key)
if (item) {
results.push({ key, value: item })
}
} catch (e) {
console.error('Error getting item', key, e)
}
}
} else {
try {
for (const item of await AsyncStorage.multiGet(keys)) {
if (item[1]) {
results.push({ key: item[0], value: item[1] })
}
}
} catch (e) {
console.error('Error getting items', e)
}
}
return results
}
private async getDatabaseKeyValues(keys: string[]) {
const results: (TransferPayload | unknown)[] = []
if (Platform.OS === 'android') {
const failedItemIds: string[] = []
for (const key of keys) {
try {
const item = await AsyncStorage.getItem(key)
if (item) {
try {
results.push(JSON.parse(item) as TransferPayload)
} catch (e) {
results.push(item)
}
}
} catch (e) {
console.error('Error getting item', key, e)
failedItemIds.push(key)
}
}
if (failedItemIds.length > 0) {
showLoadFailForItemIds(failedItemIds)
}
} else {
try {
for (const item of await AsyncStorage.multiGet(keys)) {
if (item[1]) {
try {
results.push(JSON.parse(item[1]))
} catch (e) {
results.push(item[1])
}
}
}
} catch (e) {
console.error('Error getting items', e)
}
}
return results
}
async getRawStorageValue(key: string) {
const item = await AsyncStorage.getItem(key)
if (item) {
try {
return JSON.parse(item)
} catch (e) {
return item
}
}
}
hideMobileInterfaceFromScreenshots(): void {
hide()
this.setAndroidScreenshotPrivacy(true)
}
stopHidingMobileInterfaceFromScreenshots(): void {
show()
this.setAndroidScreenshotPrivacy(false)
}
async getAllRawStorageKeyValues() {
const keys = await AsyncStorage.getAllKeys()
return this.getRawStorageKeyValues(keys)
getRawStorageValue(key: string): Promise<string | undefined> {
return this.keyValueStore.getValue(key)
}
setRawStorageValue(key: string, value: string): Promise<void> {
return AsyncStorage.setItem(key, JSON.stringify(value))
return this.keyValueStore.set(key, value)
}
removeRawStorageValue(key: string): Promise<void> {
return AsyncStorage.removeItem(key)
return this.keyValueStore.delete(key)
}
removeAllRawStorageValues(): Promise<void> {
return AsyncStorage.clear()
return this.keyValueStore.deleteAll()
}
openDatabase(): Promise<{ isNewDatabase?: boolean | undefined } | undefined> {
return Promise.resolve({ isNewDatabase: false })
}
async getAllRawDatabasePayloads<T extends TransferPayload = TransferPayload>(
getDatabaseLoadChunks(options: DatabaseLoadOptions, identifier: string): Promise<DatabaseKeysLoadChunkResponse> {
return this.findOrCreateDatabase(identifier).getLoadChunks(options)
}
async getAllDatabaseEntries<T extends TransferPayload = TransferPayload>(
identifier: ApplicationIdentifier,
): Promise<T[]> {
const keys = await this.getAllDatabaseKeys(identifier)
return this.getDatabaseKeyValues(keys) as Promise<T[]>
return this.findOrCreateDatabase(identifier).getAllEntries()
}
saveRawDatabasePayload(payload: TransferPayload, identifier: ApplicationIdentifier): Promise<void> {
return this.saveRawDatabasePayloads([payload], identifier)
}
async saveRawDatabasePayloads(payloads: TransferPayload[], identifier: ApplicationIdentifier): Promise<void> {
if (payloads.length === 0) {
return
}
await Promise.all(
payloads.map((item) => {
return AsyncStorage.setItem(this.keyForPayloadId(item.uuid, identifier), JSON.stringify(item))
}),
)
}
removeRawDatabasePayloadWithId(id: string, identifier: ApplicationIdentifier): Promise<void> {
return this.removeRawStorageValue(this.keyForPayloadId(id, identifier))
}
async removeAllRawDatabasePayloads(identifier: ApplicationIdentifier): Promise<void> {
const keys = await this.getAllDatabaseKeys(identifier)
return AsyncStorage.multiRemove(keys)
}
async getNamespacedKeychainValue(
async getDatabaseEntries<T extends TransferPayload = TransferPayload>(
identifier: ApplicationIdentifier,
): Promise<NamespacedRootKeyInKeychain | undefined> {
const keychain = await this.getRawKeychainValue()
if (!keychain) {
return
}
const namespacedValue = keychain[identifier]
if (!namespacedValue && isLegacyIdentifier(identifier)) {
return keychain as unknown as NamespacedRootKeyInKeychain
}
return namespacedValue
keys: string[],
): Promise<T[]> {
return this.findOrCreateDatabase(identifier).multiGet<T>(keys)
}
async setNamespacedKeychainValue(
value: NamespacedRootKeyInKeychain,
identifier: ApplicationIdentifier,
): Promise<void> {
let keychain = await this.getRawKeychainValue()
if (!keychain) {
keychain = {}
}
await Keychain.setKeys({
...keychain,
[identifier]: value,
})
saveDatabaseEntry(payload: TransferPayload, identifier: ApplicationIdentifier): Promise<void> {
return this.saveDatabaseEntries([payload], identifier)
}
async clearNamespacedKeychainValue(identifier: ApplicationIdentifier): Promise<void> {
const keychain = await this.getRawKeychainValue()
async saveDatabaseEntries(payloads: TransferPayload[], identifier: ApplicationIdentifier): Promise<void> {
return this.findOrCreateDatabase(identifier).setItems(payloads)
}
if (!keychain) {
return
}
removeDatabaseEntry(id: string, identifier: ApplicationIdentifier): Promise<void> {
return this.findOrCreateDatabase(identifier).deleteItem(id)
}
if (!keychain[identifier] && isLegacyIdentifier(identifier) && isLegacyMobileKeychain(keychain)) {
await this.clearRawKeychainValue()
return
}
delete keychain[identifier]
await Keychain.setKeys(keychain)
async removeAllDatabaseEntries(identifier: ApplicationIdentifier): Promise<void> {
return this.findOrCreateDatabase(identifier).deleteAll()
}
async getDeviceBiometricsAvailability() {
@@ -413,6 +227,51 @@ export class MobileDevice implements MobileDeviceInterface {
return result
}
async getNamespacedKeychainValue(
identifier: ApplicationIdentifier,
): Promise<NamespacedRootKeyInKeychain | undefined> {
const keychain = await this.getRawKeychainValue()
if (!keychain) {
return
}
const namespacedValue = keychain[identifier]
if (!namespacedValue && isLegacyIdentifier(identifier)) {
return keychain as unknown as NamespacedRootKeyInKeychain
}
return namespacedValue
}
async setNamespacedKeychainValue(
value: NamespacedRootKeyInKeychain,
identifier: ApplicationIdentifier,
): Promise<void> {
let keychain = await this.getRawKeychainValue()
if (!keychain) {
keychain = {}
}
await Keychain.setKeys({
...keychain,
[identifier]: value,
})
}
async clearNamespacedKeychainValue(identifier: ApplicationIdentifier): Promise<void> {
const keychain = await this.getRawKeychainValue()
if (!keychain) {
return
}
delete keychain[identifier]
await Keychain.setKeys(keychain)
}
async getRawKeychainValue(): Promise<RawKeychainValue | undefined> {
const result = await Keychain.getKeys()
@@ -641,4 +500,14 @@ export class MobileDevice implements MobileDeviceInterface {
async getColorScheme(): Promise<ColorSchemeName> {
return Appearance.getColorScheme()
}
hideMobileInterfaceFromScreenshots(): void {
hide()
this.setAndroidScreenshotPrivacy(true)
}
stopHidingMobileInterfaceFromScreenshots(): void {
show()
this.setAndroidScreenshotPrivacy(false)
}
}
@@ -7,7 +7,7 @@ import { OnShouldStartLoadWithRequest } from 'react-native-webview/lib/WebViewTy
import { AndroidBackHandlerService } from './AndroidBackHandlerService'
import { AppStateObserverService } from './AppStateObserverService'
import { ColorSchemeObserverService } from './ColorSchemeObserverService'
import { MobileDevice, MobileDeviceEvent } from './Lib/Interface'
import { MobileDevice, MobileDeviceEvent } from './Lib/MobileDevice'
import { IsDev } from './Lib/Utils'
const LoggingEnabled = IsDev
@@ -177,6 +177,10 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
window.ReactNativeWebView.postMessage('[web log] ' + args.join(' '));
}
console.error = (...args) => {
window.ReactNativeWebView.postMessage('[web log] ' + args.join(' '));
}
${WebProcessDeviceInterface}
${WebProcessMessageSender}
+28
View File
@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.42.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
### Features
* Added per-tag preference to use table layout and removed "Files Table View" from Labs ([dd8ccde](https://github.com/standardnotes/app/commit/dd8ccdeadc6c2fd7f7ccd66f2dc4b0081616fb2b))
## [1.41.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/models
# [1.41.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
### Features
* improve initial load performance on mobile ([#2126](https://github.com/standardnotes/app/issues/2126)) ([3c332a3](https://github.com/standardnotes/app/commit/3c332a35f6024c46020a1d6ac68a5df989804142))
## [1.40.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/models
## [1.40.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/models
## [1.40.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/models
## [1.40.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-27)
**Note:** Version bump only for package @standardnotes/models
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/models",
"version": "1.40.1",
"version": "1.42.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -10,22 +10,3 @@ export interface NamespacedRootKeyInKeychain {
}
export type RootKeyContentInStorage = RootKeyContentSpecialized
export interface LegacyRawKeychainValue {
mk: string
ak: string
version: ProtocolVersion
}
export type LegacyMobileKeychainStructure = {
offline?: {
timing?: unknown
pw?: string
}
encryptedAccountKeys?: unknown
mk: string
pw: string
ak: string
version?: string
jwt?: string
}
@@ -1,5 +1,5 @@
import { dateFromDSLDateString } from './Utils'
import { addDaysToDate, addHoursToDate } from '@standardnotes/utils'
import { addDaysToDate, addHoursToDate, addMonthsToDate, addYearsToDate } from '@standardnotes/utils'
describe('Predicate Utils', () => {
describe('dateFromDSLDateString', () => {
@@ -15,12 +15,12 @@ describe('Predicate Utils', () => {
it('should return a date object with the correct month', () => {
const date = dateFromDSLDateString('1.months.ago')
expect(date.getMonth()).toEqual(new Date().getMonth() - 1)
expect(date.getMonth()).toEqual(addMonthsToDate(new Date(), -1).getMonth())
})
it('should return a date object with the correct year', () => {
const date = dateFromDSLDateString('1.years.ago')
expect(date.getFullYear()).toEqual(new Date().getFullYear() - 1)
expect(date.getFullYear()).toEqual(addYearsToDate(new Date(), -1).getFullYear())
})
})
})
@@ -18,4 +18,5 @@ export interface TagPreferences {
editorIdentifier?: EditorIdentifier
entryMode?: 'normal' | 'daily'
panelWidth?: number
useTableView?: boolean
}
+88
View File
@@ -3,6 +3,94 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.4.99](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-09)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.98](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-07)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.97](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.96](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.95](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.94](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-05)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.93](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-05)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.92](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-05)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.91](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.90](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.89](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-04)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.88](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.87](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.86](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-03)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.85](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.84](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.83](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.82](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.81](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.80](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.79](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.78](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.77](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-27)
**Note:** Version bump only for package @standardnotes/releases
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/releases",
"version": "1.4.77",
"version": "1.4.99",
"license": "AGPL-3.0-or-later",
"main": "dist/releases.json",
"types": "dist/index.d.ts",
+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.12.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-01-06)
**Note:** Version bump only for package @standardnotes/responses
## [1.12.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-29)
**Note:** Version bump only for package @standardnotes/responses
## [1.12.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-28)
**Note:** Version bump only for package @standardnotes/responses
## [1.12.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-12-05)
**Note:** Version bump only for package @standardnotes/responses
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/responses",
"version": "1.12.10",
"version": "1.12.13",
"engines": {
"node": ">=16.0.0 <17.0.0"
},

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