Compare commits

...
Author SHA1 Message Date
StandardNotes CI d4f9a18135 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].5
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].8
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2024-04-10 18:14:48 +00:00
Aman Harwara 65c16ed246 chore: rename theme [skip e2e] 2024-04-10 23:18:26 +05:30
Aman Harwara 852ddc677d chore: fix some issues with theme [skip e2e] 2024-04-10 23:13:48 +05:30
StandardNotes CI 17458b61d1 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].7
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].9
 - @standardnotes/[email protected]
2024-04-10 10:57:00 +00:00
Aman Harwara 03da45537d chore: add proton theme [skip e2e] 2024-04-10 16:18:01 +05:30
StandardNotes CI 7332f10ff4 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].6
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].8
 - @standardnotes/[email protected]
2024-04-08 16:02:49 +00:00
Mo b6eda707bd chore: auth verification (#2867) [skip e2e] 2024-04-08 21:22:56 +05:30
StandardNotes CI a37e095907 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2024-04-04 11:31:41 +00:00
Aman Harwara ef81e9d97e chore: fix super block dragging indicator line not disappearing correctly (#2866) [skip e2e] 2024-04-04 16:53:02 +05:30
Aman Harwara c6a31f209d chore: fix tags list not scrolling correctly when dragging a tag (#2865) 2024-04-04 16:52:41 +05:30
StandardNotes CI 292153333f chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].9
2024-04-01 14:12:16 +00:00
Aman Harwara 6cef772212 refactor: link editor [skip e2e] 2024-04-01 19:33:12 +05:30
Aman Harwara f4ab9b0d97 chore: fix keyboard nav on super toolbar [skip e2e] 2024-04-01 18:26:49 +05:30
Aman Harwara 73eba38c14 fix: Fixed super note "Table of contents" not working on mobile 2024-04-01 17:34:03 +05:30
Micah Zoltu 4b19076f9b chore: fix webapp build instructions (#2856) 2024-03-31 15:43:09 +05:30
StandardNotes CI da9c412703 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].8
2024-03-28 08:36:52 +00:00
Aman Harwara 9784ff0173 chore: fix PDF export CSP error on webapp [skip e2e] 2024-03-28 13:57:49 +05:30
StandardNotes CI d8df19b0bd chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].7
2024-03-27 16:11:01 +00:00
Aman Harwara da16a779ce chore: dedupe embedded file ids when exporting a super note [skip e2e] 2024-03-27 21:31:56 +05:30
StandardNotes CI 473fb6be53 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].7
 - @standardnotes/[email protected].6
2024-03-26 15:48:01 +00:00
Aman Harwara d5cac8e32d chore: trigger release [skip e2e] 2024-03-26 21:08:45 +05:30
Aman Harwara 45ca99c627 fix: Fixed issue with system color scheme on mobile 2024-03-26 21:08:04 +05:30
StandardNotes CI 8a6e123fbc chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].5
2024-03-26 13:35:04 +00:00
Karol Sójko 914c444349 chore(web): remove unused setting for failed email backups - skip e2e (#2863)
* chore(web): remove unused setting for failed email backups

* adjust tests
2024-03-26 14:25:19 +01:00
StandardNotes CI bf8ad837ef chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].5
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].6
 - @standardnotes/[email protected].4
2024-03-22 19:21:42 +00:00
Aman Harwara e3ae421f7c chore: fix issues with multiple non-layerable themes being active on color scheme change [skip e2e] 2024-03-23 00:43:02 +05:30
Aman Harwara a162294d04 chore: fix csp errors in dev server 2024-03-23 00:25:02 +05:30
Aman Harwara f0613e7af5 chore: fix theme not toggling when changing auto-light/dark theme selection 2024-03-23 00:24:41 +05:30
Aman Harwara 7967ddead7 fix: Fixed issue with system color scheme not being applied correctly on start 2024-03-23 00:01:54 +05:30
StandardNotes CI f868989bb5 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
2024-03-22 13:59:33 +00:00
Aman Harwara eb5e5e11e0 chore: fix dark mode keyboard shortcut [skip e2e] 2024-03-22 19:19:23 +05:30
StandardNotes CI 0d1831ea49 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
2024-03-22 08:55:23 +00:00
Karol Sójko a22000242a chore: block disabling 2FA if U2F authenticators present - skip e2e (#2862)
* chore: block disabling 2FA if U2F authenticators present

* chore: remove the u2f wrapper component

* chore: adjust fetching 2fa status

* chore: fix property name

* chore: remove wrapper
2024-03-22 09:45:15 +01:00
Karol Sójko 4068d5b480 chore(web): prevent from adding U2F if 2FA is not enabled (#2861) 2024-03-20 15:31:40 +01:00
StandardNotes CI fd0d08c153 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
2024-03-14 15:03:24 +00:00
Aman Harwara adef74f23f chore: release [skip e2e] 2024-03-14 20:24:30 +05:30
Aman Harwara b90c725f96 chore: remove unused patch [skip e2] 2024-03-14 20:13:15 +05:30
Aman Harwara 74b459cae0 chore: update changelog [skip e2e] 2024-03-14 20:12:23 +05:30
Aman Harwara c1e9a7fe40 chore: revert changes [skip e2e] 2024-03-14 20:11:17 +05:30
Aman Harwara edf8de4468 Revert "chore: sync lexical with patch [skip e2e]"
This reverts commit 45c661c136.
2024-03-14 20:10:55 +05:30
Aman Harwara bb81c8acfc Revert "feat: Markdown text is now parsed correctly when pasted"
This reverts commit c5ca4a9857.
2024-03-14 20:10:35 +05:30
StandardNotes CI 414a2dda0b chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
2024-03-14 13:47:55 +00:00
Aman Harwara 45c661c136 chore: sync lexical with patch [skip e2e] 2024-03-14 19:09:00 +05:30
Aman Harwara c5ca4a9857 feat: Markdown text is now parsed correctly when pasted 2024-03-14 19:01:39 +05:30
StandardNotes CI 56813909bb chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].5
 - @standardnotes/[email protected]
2024-03-14 10:21:01 +00:00
Karol Sójkoandmoughxyz 7a4172ad11 chore: add e2e test for refresh tokens cooldown period - skip e2e (#2860)
* chore: add e2e test for refresh tokens cooldown period

* chore: fix refreshing session in e2e

* chore: fix session refresh cooldown test

* chore: fix e2e test

* Add dropped response simulation test

---------

Co-authored-by: moughxyz <[email protected]>
2024-03-14 11:11:17 +01:00
StandardNotes CI e97e788b5f chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected]
2024-03-13 18:48:39 +00:00
Aman Harwara 20a9ef0dad chore: stable scrollbar gutters on windows [skip e2e] 2024-03-14 00:09:50 +05:30
Aman Harwara 670f27b9cd chore: update changelog [skip ci] 2024-03-12 19:41:34 +05:30
Aman Harwara f45d854006 chore: update changelog [skip e2e] 2024-03-12 19:34:38 +05:30
StandardNotes CI 5043b4c110 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2024-03-12 11:30:04 +00:00
Aman Harwara e1981f4eae chore: add "Clear formatting" option to text format menu and make selected options clearer by showing check if selected [skip e2e] 2024-03-12 16:51:08 +05:30
Aman Harwara 3fb6d10a7f chore: fix issue with super toolbar menu items not working on mobile [skip e2e] 2024-03-12 16:33:52 +05:30
StandardNotes CI 498cd1b27c chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2024-03-11 19:25:47 +00:00
moughxyz 6d872cd45a fix: use API v0 for Android [skip e2e] 2024-03-11 14:15:15 -05:00
StandardNotes CI 9e2d496804 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2024-03-11 10:50:23 +00:00
Karol Sójko 7febc1fac6 chore: fix calling subscription settings endpoints - skip e2e 2024-03-11 11:40:58 +01:00
StandardNotes CI 6f571936c3 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2024-03-11 10:21:38 +00:00
Karol Sójko 065f3562f4 chore: fix muting sign in emails - skip e2e (#2859)
* chore: fix muting sign in emails - skip e2e

* chore: fix api version for e2e tests
2024-03-11 11:12:23 +01:00
StandardNotes CI 41f542d1c5 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2024-03-08 05:54:51 +00:00
Aman Harwara 94840a7afb chore: trigger release [skip e2e] 2024-03-08 11:15:18 +05:30
StandardNotes CI fb19b37d5b chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
2024-03-07 15:40:21 +00:00
Mo 3b2f761661 fix: use API v0 on iOS (#2858) [skip e2e] 2024-03-07 09:29:46 -06:00
StandardNotes CI b28b59e4a0 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2024-03-07 12:38:06 +00:00
Karol Sójko 9238759d38 chore: add building web app image - skip e2e (#2857) 2024-03-07 13:28:13 +01:00
StandardNotes CI d2404ba276 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].9
 - @standardnotes/[email protected]
2024-03-06 11:43:03 +00:00
Karol Sójko 7301acd36c chore: fix e2e tests for no cookie support setup - skip e2e 2024-03-06 12:33:30 +01:00
StandardNotes CI bf997e356c chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2024-03-05 14:20:50 +00:00
Aman Harwara c151c3c6d7 chore: fix issue with sibling lists not being merged correctly in Super [skip e2e] 2024-03-05 19:39:49 +05:30
StandardNotes CI 6af7f66f46 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected].8
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected]
2024-03-05 08:34:17 +00:00
Karol Sójko 1d0e8cfc7f chore: switch api to cookie based sessions - skip e2e (#2854)
* chore: switch api to cookie based sessions - skip e2e

* chore: fix legacy http service to include api version in requests - skip e2e
2024-03-05 09:25:53 +01:00
StandardNotes CI f3f5c63185 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].7
 - @standardnotes/[email protected]
2024-03-01 13:51:47 +00:00
Karol Sójko 1651a24370 chore: replace sncrypto web with a published version - skip e2e 2024-03-01 14:41:58 +01:00
118 changed files with 2706 additions and 1005 deletions
+38
View File
@@ -103,6 +103,44 @@ jobs:
trigger_workflow: true
wait_workflow: true
publish-web-docker:
name: Build and publish Docker Image for Web App
needs: [e2e-base, e2e-vaults]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
token: ${{ secrets.CI_PAT_TOKEN }}
fetch-depth: 0
- name: Set up Node
uses: actions/setup-node@v3
with:
registry-url: 'https://registry.npmjs.org'
node-version-file: '.nvmrc'
cache: 'yarn'
- name: Install dependencies
run: yarn install --immutable
- name: Build
run: yarn build:web
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Publish SNJS Docker image for E2E testing
run: |
cd packages/web
docker build -t standardnotes/web:${{ github.sha }} .
docker tag standardnotes/web:${{ github.sha }} standardnotes/web:latest
docker push standardnotes/web:${{ github.sha }}
docker push standardnotes/web:latest
publish:
name: Publish to NPM
needs: [e2e-base, e2e-vaults]
+6 -5
View File
@@ -49,11 +49,12 @@ Questions? Find answers on our [Help page](https://standardnotes.com/help).
Our web app is compiled into a folder of static HTML, JS, and CSS files. You can serve these files behind a web server to get started:
1. Clone the repo
2. `cd packages/web`
3. `yarn build`
4. `cd dist`
5. You can then use Python to serve this folder over http: `python -m http.server 8080`
1. `git clone https://github.com/standardnotes/app.git`
2. `cd app`
3. `yarn install`
4. `yarn build:web`
5. `cd packages/web`
6. You can then use Python to serve this folder over http: `python -m http.server 8080`
You can now access the app at `http://localhost:8080`.
+26
View File
@@ -3,6 +3,32 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.26.87](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/api
## [1.26.86](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/api
## [1.26.85](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/api
## [1.26.84](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/api
## [1.26.83](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
### Bug Fixes
* use API v0 on iOS ([#2858](https://github.com/standardnotes/app/issues/2858)) [skip e2e] ([3b2f761](https://github.com/standardnotes/app/commit/3b2f76166126a5b11f35b64aacefa37618622c3d))
## [1.26.82](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/api
## [1.26.81](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-02-22)
**Note:** Version bump only for package @standardnotes/api
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api",
"version": "1.26.81",
"version": "1.26.87",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -1,3 +1,4 @@
export enum ApiVersion {
v0 = '20200115',
v1 = '20240226',
}
@@ -15,7 +15,10 @@ import { AuthApiServiceInterface } from './AuthApiServiceInterface'
export class AuthApiService implements AuthApiServiceInterface {
private operationsInProgress: Map<AuthApiOperations, boolean>
constructor(private authServer: AuthServerInterface) {
constructor(
private authServer: AuthServerInterface,
private apiVersion: ApiVersion,
) {
this.operationsInProgress = new Map()
}
@@ -50,7 +53,7 @@ export class AuthApiService implements AuthApiServiceInterface {
try {
const response = await this.authServer.recoveryKeyParams({
api_version: ApiVersion.v0,
api_version: this.apiVersion,
code_challenge: dto.codeChallenge,
recovery_codes: dto.recoveryCodes,
username: dto.username,
@@ -69,6 +72,7 @@ export class AuthApiService implements AuthApiServiceInterface {
password: string
codeVerifier: string
recoveryCodes: string
hvmToken?: string
}): Promise<HttpResponse<SignInWithRecoveryCodesResponseBody>> {
if (this.operationsInProgress.get(AuthApiOperations.SignInWithRecoveryCodes)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
@@ -78,11 +82,12 @@ export class AuthApiService implements AuthApiServiceInterface {
try {
const response = await this.authServer.signInWithRecoveryCodes({
api_version: ApiVersion.v0,
api_version: this.apiVersion,
code_verifier: dto.codeVerifier,
password: dto.password,
recovery_codes: dto.recoveryCodes,
username: dto.username,
hvm_token: dto.hvmToken,
})
return response
@@ -17,5 +17,6 @@ export interface AuthApiServiceInterface {
password: string
codeVerifier: string
recoveryCodes: string
hvmToken?: string
}): Promise<HttpResponse<SignInWithRecoveryCodesResponseBody>>
}
@@ -23,7 +23,10 @@ import { GetUserSubscriptionRequestParams } from '../../Request/Subscription/Get
export class SubscriptionApiService implements SubscriptionApiServiceInterface {
private operationsInProgress: Map<SubscriptionApiOperations, boolean>
constructor(private subscriptionServer: SubscriptionServerInterface) {
constructor(
private subscriptionServer: SubscriptionServerInterface,
private apiVersion: ApiVersion,
) {
this.operationsInProgress = new Map()
}
@@ -36,7 +39,7 @@ export class SubscriptionApiService implements SubscriptionApiServiceInterface {
try {
const response = await this.subscriptionServer.listInvites({
[ApiEndpointParam.ApiVersion]: ApiVersion.v0,
[ApiEndpointParam.ApiVersion]: this.apiVersion,
})
return response
@@ -56,7 +59,7 @@ export class SubscriptionApiService implements SubscriptionApiServiceInterface {
try {
const response = await this.subscriptionServer.cancelInvite({
[ApiEndpointParam.ApiVersion]: ApiVersion.v0,
[ApiEndpointParam.ApiVersion]: this.apiVersion,
inviteUuid,
})
@@ -77,7 +80,7 @@ export class SubscriptionApiService implements SubscriptionApiServiceInterface {
try {
const response = await this.subscriptionServer.invite({
[ApiEndpointParam.ApiVersion]: ApiVersion.v0,
[ApiEndpointParam.ApiVersion]: this.apiVersion,
identifier: inviteeEmail,
})
@@ -22,6 +22,7 @@ export class UserApiService implements UserApiServiceInterface {
constructor(
private userServer: UserServerInterface,
private userRequestServer: UserRequestServerInterface,
private apiVersion: ApiVersion,
) {
this.operationsInProgress = new Map()
}
@@ -65,6 +66,7 @@ export class UserApiService implements UserApiServiceInterface {
async register(registerDTO: {
email: string
serverPassword: string
hvmToken?: string
keyParams: RootKeyParamsInterface
ephemeral: boolean
}): Promise<HttpResponse<UserRegistrationResponseBody>> {
@@ -72,9 +74,10 @@ export class UserApiService implements UserApiServiceInterface {
try {
const response = await this.userServer.register({
[ApiEndpointParam.ApiVersion]: ApiVersion.v0,
[ApiEndpointParam.ApiVersion]: this.apiVersion,
password: registerDTO.serverPassword,
email: registerDTO.email,
hvm_token: registerDTO.hvmToken,
ephemeral: registerDTO.ephemeral,
...registerDTO.keyParams.getPortableValue(),
})
@@ -92,7 +95,7 @@ export class UserApiService implements UserApiServiceInterface {
try {
const response = await this.userServer.update({
[ApiEndpointParam.ApiVersion]: ApiVersion.v0,
[ApiEndpointParam.ApiVersion]: this.apiVersion,
user_uuid: updateDTO.userUuid,
})
@@ -11,6 +11,7 @@ export interface UserApiServiceInterface {
register(registerDTO: {
email: string
serverPassword: string
hvmToken?: string
keyParams: RootKeyParamsInterface
ephemeral: boolean
}): Promise<HttpResponse<UserRegistrationResponseBody>>
+46 -15
View File
@@ -1,6 +1,6 @@
import { LoggerInterface, joinPaths, sleep } from '@standardnotes/utils'
import { Environment } from '@standardnotes/models'
import { LegacySession, Session, SessionToken } from '@standardnotes/domain-core'
import { LegacySession, Result, Session, SessionToken } from '@standardnotes/domain-core'
import {
HttpStatusCode,
HttpRequestParams,
@@ -9,9 +9,11 @@ import {
HttpResponse,
HttpResponseMeta,
isErrorResponse,
ApiEndpointParam,
} from '@standardnotes/responses'
import { HttpServiceInterface } from './HttpServiceInterface'
import { ApiVersion } from '../Api'
import { Paths } from '../Server/Auth/Paths'
import { SessionRefreshResponseBody } from '../Response/Auth/SessionRefreshResponseBody'
import { FetchRequestHandler } from './FetchRequestHandler'
@@ -21,10 +23,11 @@ import { HttpRequestOptions } from './HttpRequestOptions'
export class HttpService implements HttpServiceInterface {
private session?: Session | LegacySession
private __latencySimulatorMs?: number
private __simulateNextSessionRefreshResponseDrop = false
private declare host: string
loggingEnabled = false
private inProgressRefreshSessionPromise?: Promise<boolean>
private inProgressRefreshSessionPromise?: Promise<Result<HttpResponse<SessionRefreshResponseBody>>>
private updateMetaCallback!: (meta: HttpResponseMeta) => void
private refreshSessionCallback!: (session: Session) => void
@@ -34,6 +37,7 @@ export class HttpService implements HttpServiceInterface {
private environment: Environment,
private appVersion: string,
private snjsVersion: string,
private apiVersion: ApiVersion,
private logger: LoggerInterface,
) {
this.requestHandler = new FetchRequestHandler(this.snjsVersion, this.appVersion, this.environment, this.logger)
@@ -145,6 +149,10 @@ export class HttpService implements HttpServiceInterface {
await sleep(this.__latencySimulatorMs, true)
}
httpRequest.params = httpRequest.params
? this.params(httpRequest.params as Record<string | number | symbol, unknown>)
: undefined
const isRefreshRequest = httpRequest.url === joinPaths(this.host, Paths.v1.refreshSession)
if (this.inProgressRefreshSessionPromise && !isRefreshRequest) {
await this.inProgressRefreshSessionPromise
@@ -166,12 +174,19 @@ export class HttpService implements HttpServiceInterface {
if (this.inProgressRefreshSessionPromise) {
await this.inProgressRefreshSessionPromise
} else {
this.inProgressRefreshSessionPromise = this.refreshSession()
const isSessionRefreshed = await this.inProgressRefreshSessionPromise
this.inProgressRefreshSessionPromise = undefined
const hasSessionTokenRenewedInBetweenOurRequest = httpRequest.authentication !== this.getSessionAccessToken()
if (!hasSessionTokenRenewedInBetweenOurRequest) {
this.inProgressRefreshSessionPromise = this.refreshSession()
const isSessionRefreshedResultOrError = await this.inProgressRefreshSessionPromise
let isSessionRefreshed = false
if (!isSessionRefreshedResultOrError.isFailed()) {
isSessionRefreshed = !isErrorResponse(isSessionRefreshedResultOrError.getValue())
}
this.inProgressRefreshSessionPromise = undefined
if (!isSessionRefreshed) {
return response
if (!isSessionRefreshed) {
return response
}
}
}
@@ -183,13 +198,13 @@ export class HttpService implements HttpServiceInterface {
return response
}
async refreshSession(): Promise<boolean> {
async refreshSession(): Promise<Result<HttpResponse<SessionRefreshResponseBody>>> {
if (!this.session) {
return false
return Result.fail('No session to refresh')
}
if (this.session instanceof LegacySession) {
return false
return Result.fail('Cannot refresh legacy session')
}
const response = await this.post<SessionRefreshResponseBody>(Paths.v1.refreshSession, {
@@ -197,8 +212,13 @@ export class HttpService implements HttpServiceInterface {
refresh_token: this.session.refreshToken.value,
})
if (this.__simulateNextSessionRefreshResponseDrop) {
this.__simulateNextSessionRefreshResponseDrop = false
return Result.fail('Simulating a dropped response')
}
if (isErrorResponse(response)) {
return false
return Result.ok(response)
}
if (response.meta) {
@@ -210,7 +230,7 @@ export class HttpService implements HttpServiceInterface {
response.data.session.access_expiration,
)
if (accessTokenOrError.isFailed()) {
return false
return Result.fail(accessTokenOrError.getError())
}
const accessToken = accessTokenOrError.getValue()
@@ -220,20 +240,31 @@ export class HttpService implements HttpServiceInterface {
response.data.session.refresh_expiration,
)
if (refreshTokenOrError.isFailed()) {
return false
return Result.fail(refreshTokenOrError.getError())
}
const refreshToken = refreshTokenOrError.getValue()
const sessionOrError = Session.create(accessToken, refreshToken, response.data.session.readonly_access)
if (sessionOrError.isFailed()) {
return false
return Result.fail(sessionOrError.getError())
}
this.setSession(sessionOrError.getValue())
this.refreshSessionCallback(this.session)
return true
return Result.ok(response)
}
private params(inParams: Record<string | number | symbol, unknown>): HttpRequestParams {
const params = {
...inParams,
...{
[ApiEndpointParam.ApiVersion]: this.apiVersion,
},
}
return params
}
}
@@ -1,7 +1,8 @@
import { LegacySession, Session } from '@standardnotes/domain-core'
import { LegacySession, Result, Session } from '@standardnotes/domain-core'
import { HttpRequest, HttpRequestParams, HttpResponse, HttpResponseMeta } from '@standardnotes/responses'
import { HttpRequestOptions } from './HttpRequestOptions'
import { SessionRefreshResponseBody } from '../Response'
export interface HttpServiceInterface {
setHost(host: string): void
@@ -16,7 +17,7 @@ export interface HttpServiceInterface {
runHttp<T>(httpRequest: HttpRequest): Promise<HttpResponse<T>>
setSession(session: Session | LegacySession): void
refreshSession(): Promise<boolean>
refreshSession(): Promise<Result<HttpResponse<SessionRefreshResponseBody>>>
setCallbacks(
updateMetaCallback: (meta: HttpResponseMeta) => void,
refreshSessionCallback: (session: Session) => void,
@@ -4,4 +4,5 @@ export interface SignInWithRecoveryCodesRequestParams {
password: string
code_verifier: string
recovery_codes: string
hvm_token?: string
}
@@ -6,5 +6,6 @@ export type UserRegistrationRequestParams = AnyKeyParamsContent & {
[additionalParam: string]: unknown
password: string
email: string
hvm_token?: string
ephemeral: boolean
}
+108
View File
@@ -3,6 +3,114 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.450](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.449](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.448](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.447](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-04)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.446](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-01)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.445](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-28)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.444](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-27)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.443](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.442](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.441](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.440](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.439](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.438](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.437](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.436](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.435](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-13)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.434](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-12)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.433](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.432](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.431](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.430](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-08)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.429](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.428](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.427](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-06)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.426](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.425](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.424](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.423](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)
**Note:** Version bump only for package @standardnotes/clipper
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@standardnotes/clipper",
"description": "Web clipper browser extension for Standard Notes",
"version": "1.1.423",
"version": "1.1.450",
"private": true,
"scripts": {
"build-mv2": "yarn clean && webpack --config ./webpack.config.prod.js",
+108
View File
@@ -3,6 +3,114 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.110.52](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.51](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.50](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.49](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-04)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.48](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-01)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.47](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-28)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.46](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-27)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.45](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.44](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.43](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.42](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.41](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.40](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.39](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.38](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.37](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-13)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.36](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-12)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.35](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.34](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.33](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.32](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-08)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.31](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.30](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.29](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-06)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.28](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.27](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.26](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)
**Note:** Version bump only for package @standardnotes/desktop
## [3.110.25](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)
**Note:** Version bump only for package @standardnotes/desktop
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@standardnotes/desktop",
"main": "./app/dist/index.js",
"version": "3.110.25",
"version": "3.110.52",
"license": "AGPL-3.0",
"author": "Standard Notes.",
"private": true,
+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.21.105](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/encryption
## [1.21.104](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/encryption
## [1.21.103](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/encryption
## [1.21.102](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-02-17)
**Note:** Version bump only for package @standardnotes/encryption
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/encryption",
"version": "1.21.102",
"version": "1.21.105",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.61.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/features
## [1.61.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/features
## [1.61.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-30)
### Bug Fixes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/features",
"version": "1.61.1",
"version": "1.61.3",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -28,6 +28,7 @@ export class NativeFeatureIdentifier extends ValueObject<NativeFeatureIdentifier
MidnightTheme: 'org.standardnotes.theme-midnight',
SolarizedDarkTheme: 'org.standardnotes.theme-solarized-dark',
TitaniumTheme: 'org.standardnotes.theme-titanium',
ProtonTheme: 'com.standardnotes.theme-proton',
PlainEditor: 'com.standardnotes.plain-text',
SuperEditor: 'com.standardnotes.super-editor',
+14 -1
View File
@@ -97,5 +97,18 @@ export function themes(): ThemeFeatureDescription[] {
no_mobile: true,
})
return [midnight, futura, solarizedDark, autobiography, dark, titanium, dynamic]
const proton: ThemeFeatureDescription = FillThemeComponentDefaults({
availableInRoles: [RoleName.NAMES.CoreUser, RoleName.NAMES.PlusUser, RoleName.NAMES.ProUser],
name: 'Carbon',
identifier: NativeFeatureIdentifier.TYPES.ProtonTheme,
permission_name: PermissionName.ProtonTheme,
dock_icon: {
type: 'circle',
background_color: '#16141c',
foreground_color: '#ffffff',
border_color: '#4a4658',
},
})
return [midnight, futura, solarizedDark, autobiography, dark, proton, titanium, dynamic]
}
@@ -40,4 +40,5 @@ export enum PermissionName {
Clipper = 'app:clipper',
Vaults = 'app:vaults',
SharedVaults = 'server:shared-vaults',
ProtonTheme = 'theme:proton',
}
+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.28.120](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.28.119](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.28.118](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.28.117](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-02-17)
**Note:** Version bump only for package @standardnotes/filepicker
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/filepicker",
"version": "1.28.117",
"version": "1.28.120",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+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.20.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/files
## [1.20.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/files
## [1.20.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/files
## [1.20.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-02-17)
**Note:** Version bump only for package @standardnotes/files
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files",
"version": "1.20.2",
"version": "1.20.5",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+112
View File
@@ -3,6 +3,118 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.58.109](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.108](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.107](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.106](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-04)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.105](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-01)
### Bug Fixes
* Fixed super note "Table of contents" not working on mobile ([73eba38](https://github.com/standardnotes/app/commit/73eba38c1444e85839d771fb297e3035eabd99c8))
## [3.58.104](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-28)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.103](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-27)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.102](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.101](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.100](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.99](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.98](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.97](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.96](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.95](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.94](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-13)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.93](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-12)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.92](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.91](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.90](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.89](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-08)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.88](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
### Bug Fixes
* use API v0 on iOS ([#2858](https://github.com/standardnotes/app/issues/2858)) [skip e2e] ([3b2f761](https://github.com/standardnotes/app/commit/3b2f76166126a5b11f35b64aacefa37618622c3d))
## [3.58.87](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.86](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-06)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.85](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.84](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.83](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)
**Note:** Version bump only for package @standardnotes/mobile
## [3.58.82](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)
**Note:** Version bump only for package @standardnotes/mobile
+1 -1
View File
@@ -158,7 +158,7 @@ platform :android do
desc 'Deploy production app'
lane :prod do
version = 3_002_000 + ENV['BUILD_NUMBER'].to_i
version = 3_004_000 + ENV['BUILD_NUMBER'].to_i
deploy_android 'prod', version
end
end
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/mobile",
"version": "3.58.82",
"version": "3.58.109",
"author": "Standard Notes.",
"private": true,
"license": "AGPL-3.0",
+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.55.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/models
## [1.55.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/models
## [1.55.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/models
# [1.55.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-02-17)
### Features
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/models",
"version": "1.55.0",
"version": "1.55.3",
"publishConfig": {
"access": "public"
},
+108
View File
@@ -3,6 +3,114 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.4.745](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.744](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.743](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.742](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-04)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.741](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-01)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.740](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-28)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.739](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-27)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.738](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.737](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.736](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.735](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.734](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.733](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.732](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.731](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.730](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-13)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.729](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-12)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.728](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.727](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.726](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.725](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-08)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.724](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.723](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.722](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-06)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.721](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.720](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.719](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.718](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)
**Note:** Version bump only for package @standardnotes/releases
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/releases",
"version": "1.4.718",
"version": "1.4.745",
"license": "AGPL-3.0",
"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.13.56](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/responses
## [1.13.55](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/responses
## [1.13.54](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/responses
## [1.13.53](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-30)
**Note:** Version bump only for package @standardnotes/responses
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/responses",
"version": "1.13.53",
"version": "1.13.56",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -0,0 +1,3 @@
export type MetaEndpointResponse = {
captchaUIUrl: string | null
}
@@ -26,6 +26,30 @@ export function isErrorResponse<T>(response: HttpResponse<T>): response is HttpE
return (response.data as HttpErrorResponseBody)?.error != undefined || response.status >= 400
}
export function getCaptchaHeader<T>(response: HttpResponse<T>) {
const captchaHeader = response.headers?.get('x-captcha-required')
if (captchaHeader) {
return captchaHeader
}
return null
}
export function getErrorMessageFromErrorResponseBody(data: HttpErrorResponseBody, defaultMessage?: string): string {
let errorMessage = defaultMessage || 'Unknown error'
if (
data &&
typeof data === 'object' &&
'error' in data &&
data.error &&
typeof data.error === 'object' &&
'message' in data.error
) {
errorMessage = data.error.message as string
}
return errorMessage
}
export function getErrorFromErrorResponse(response: HttpErrorResponse): HttpError {
const embeddedError = response.data.error
if (embeddedError) {
+1
View File
@@ -13,6 +13,7 @@ export * from './Auth/SignInData'
export * from './Auth/SignInResponse'
export * from './Auth/SignOutResponse'
export * from './Auth/User'
export * from './Auth/MetaEndpointResponse'
/** Temps are awaiting final publish state on server repo */
export * from './Temp/SharedVaultMoveType'
+32
View File
@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.70.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/services
## [1.70.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/services
## [1.70.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/services
## [1.70.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
### Bug Fixes
* Fixed issue with system color scheme not being applied correctly on start ([7967dde](https://github.com/standardnotes/app/commit/7967ddead790d89478554cd6a96429fd06958590))
## [1.70.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/services
## [1.70.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
### Bug Fixes
* use API v0 on iOS ([#2858](https://github.com/standardnotes/app/issues/2858)) [skip e2e] ([3b2f761](https://github.com/standardnotes/app/commit/3b2f76166126a5b11f35b64aacefa37618622c3d))
## [1.70.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/services
## [1.70.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-02-22)
**Note:** Version bump only for package @standardnotes/services
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/services",
"version": "1.70.1",
"version": "1.70.8",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -1,3 +1,4 @@
import { ApiVersion } from '@standardnotes/api'
import { Environment, Platform, ApplicationIdentifier } from '@standardnotes/models'
import { AlertService, DeviceInterface } from '@standardnotes/services'
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
@@ -39,4 +40,6 @@ export interface RequiredApplicationOptions {
* Version of client application.
*/
appVersion: string
apiVersion: ApiVersion
}
@@ -13,8 +13,10 @@ export interface AuthClientInterface {
password: string
codeVerifier: string
recoveryCodes: string
hvmToken?: string
}): Promise<
| {
success: true
keyParams: AnyKeyParamsContent
session: SessionBody
user: {
@@ -23,6 +25,9 @@ export interface AuthClientInterface {
protocolVersion: string
}
}
| false
| {
success: false
captchaURL: string
}
>
}
@@ -1,6 +1,6 @@
import { AuthApiServiceInterface } from '@standardnotes/api'
import { AnyKeyParamsContent } from '@standardnotes/common'
import { isErrorResponse, SessionBody } from '@standardnotes/responses'
import { isErrorResponse, getCaptchaHeader } from '@standardnotes/responses'
import { InternalEventBusInterface } from '../Internal/InternalEventBusInterface'
import { AbstractService } from '../Service/AbstractService'
@@ -45,37 +45,39 @@ export class AuthManager extends AbstractService implements AuthClientInterface
}
}
async signInWithRecoveryCodes(dto: {
username: string
password: string
codeVerifier: string
recoveryCodes: string
}): Promise<
| {
keyParams: AnyKeyParamsContent
session: SessionBody
user: {
uuid: string
email: string
protocolVersion: string
}
}
| false
> {
async signInWithRecoveryCodes(
dto: Parameters<AuthClientInterface['signInWithRecoveryCodes']>[0],
): ReturnType<AuthClientInterface['signInWithRecoveryCodes']> {
try {
const result = await this.authApiService.signInWithRecoveryCodes(dto)
const captchaURL = getCaptchaHeader(result)
if (captchaURL) {
return {
success: false,
captchaURL,
}
}
if (isErrorResponse(result)) {
return false
return {
success: false,
captchaURL: '',
}
}
return {
success: true,
keyParams: result.data.key_params as AnyKeyParamsContent,
session: result.data.session,
user: result.data.user,
}
} catch (error) {
return false
return {
success: false,
captchaURL: '',
}
}
}
}
@@ -36,7 +36,8 @@ export interface ComponentManagerInterface {
getDefaultEditorIdentifier(currentTag?: SNTag): string
isThemeActive(theme: UIFeature<ThemeFeatureDescription>): boolean
toggleTheme(theme: UIFeature<ThemeFeatureDescription>): Promise<void>
toggleTheme(theme: UIFeature<ThemeFeatureDescription>, skipEntitlementCheck?: boolean): Promise<void>
toggleOtherNonLayerableThemes(uiFeature: UIFeature<ThemeFeatureDescription>): void
getActiveThemes(): UIFeature<ThemeFeatureDescription>[]
getActiveThemesIdentifiers(): { features: NativeFeatureIdentifier[]; uuids: Uuid[] }
@@ -30,13 +30,14 @@ export interface SessionsClientInterface {
revokeAllOtherSessions(): Promise<void>
isCurrentSessionReadOnly(): boolean | undefined
register(email: string, password: string, ephemeral: boolean): Promise<UserRegistrationResponseBody>
register(email: string, password: string, hvmToken: string, ephemeral: boolean): Promise<UserRegistrationResponseBody>
signIn(
email: string,
password: string,
strict: boolean,
ephemeral: boolean,
minAllowedVersion?: ProtocolVersion,
hvmToken?: string,
): Promise<SessionManagerResponse>
bypassChecksAndSignInWithRootKey(
email: string,
@@ -142,6 +142,7 @@ export class UserService
public async register(
email: string,
password: string,
hvmToken: string,
ephemeral = false,
mergeLocal = true,
): Promise<UserRegistrationResponseBody> {
@@ -157,7 +158,7 @@ export class UserService
try {
this.lockSyncing()
const response = await this.sessions.register(email, password, ephemeral)
const response = await this.sessions.register(email, password, hvmToken, ephemeral)
await this.notifyEventSync(AccountEvent.SignedInOrRegistered, {
payload: {
@@ -190,6 +191,7 @@ export class UserService
ephemeral = false,
mergeLocal = true,
awaitSync = false,
hvmToken?: string,
): Promise<HttpResponse<SignInResponse>> {
if (this.encryption.hasAccount()) {
throw Error('Tried to sign in when an account already exists.')
@@ -205,7 +207,7 @@ export class UserService
/** Prevent a timed sync from occuring while signing in. */
this.lockSyncing()
const { response } = await this.sessions.signIn(email, password, strict, ephemeral)
const { response } = await this.sessions.signIn(email, password, strict, ephemeral, undefined, hvmToken)
if (!isErrorResponse(response)) {
const notifyingFunction = awaitSync ? this.notifyEventSync.bind(this) : this.notifyEvent.bind(this)
@@ -21,6 +21,7 @@ export interface UserServiceInterface extends AbstractService<AccountEvent, Acco
register(
email: string,
password: string,
hvmToken: string,
ephemeral: boolean,
mergeLocal: boolean,
): Promise<UserRegistrationResponseBody>
@@ -31,6 +32,7 @@ export interface UserServiceInterface extends AbstractService<AccountEvent, Acco
ephemeral: boolean,
mergeLocal: boolean,
awaitSync: boolean,
hvmToken?: string,
): Promise<HttpResponse<SignInResponse>>
deleteAccount(): Promise<{
error: boolean
-1
View File
@@ -203,7 +203,6 @@ export * from './User/SignedInOrRegisteredEventPayload'
export * from './User/SignedOutEventPayload'
export * from './User/UserService'
export * from './User/UserServiceInterface'
export * from './User/UserServiceInterface'
export * from './UserEvent/NotificationService'
export * from './UserEvent/NotificationServiceEvent'
export * from './Vault/UseCase/AuthorizeVaultDeletion'
+52
View File
@@ -3,6 +3,58 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.208.18](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/snjs
## [2.208.17](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/snjs
## [2.208.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/snjs
## [2.208.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)
**Note:** Version bump only for package @standardnotes/snjs
## [2.208.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
### Bug Fixes
* Fixed issue with system color scheme not being applied correctly on start ([7967dde](https://github.com/standardnotes/app/commit/7967ddead790d89478554cd6a96429fd06958590))
## [2.208.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/snjs
## [2.208.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/snjs
## [2.208.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/snjs
## [2.208.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
### Bug Fixes
* use API v0 on iOS ([#2858](https://github.com/standardnotes/app/issues/2858)) [skip e2e] ([3b2f761](https://github.com/standardnotes/app/commit/3b2f76166126a5b11f35b64aacefa37618622c3d))
## [2.208.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-06)
**Note:** Version bump only for package @standardnotes/snjs
## [2.208.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/snjs
## [2.208.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)
**Note:** Version bump only for package @standardnotes/snjs
## [2.208.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)
**Note:** Version bump only for package @standardnotes/snjs
-12
View File
@@ -3,22 +3,10 @@
/* Used for running mocha tests */
const connect = require('connect')
const serveStatic = require('serve-static')
const fs = require('fs')
const isDev = process.argv[2] === '--dev'
const port = isDev ? 9002 : 9001
const snCryptoDistFilePath = `${__dirname}/../sncrypto-web/dist/sncrypto-web.js`
if (!fs.existsSync(snCryptoDistFilePath)) {
console.error(
`Could not find sncrypto dist file under: ${snCryptoDistFilePath}. Please consider building the project first`,
)
process.exit(1)
}
fs.copyFileSync(snCryptoDistFilePath, `${__dirname}/mocha/vendor/sncrypto-web.js`)
connect()
.use(serveStatic(__dirname))
.listen(port, () => {
+14 -6
View File
@@ -98,6 +98,7 @@ import {
SignInResponse,
ClientDisplayableError,
SessionListEntry,
MetaEndpointResponse,
} from '@standardnotes/responses'
import {
SyncService,
@@ -117,7 +118,7 @@ import {
LoggerInterface,
canBlockDeinit,
} from '@standardnotes/utils'
import { UuidString, ApplicationEventPayload } from '../Types'
import { UuidString } from '../Types'
import { applicationEventForSyncEvent } from '@Lib/Application/Event'
import { BackupServiceInterface, FilesClientInterface } from '@standardnotes/files'
import { ComputePrivateUsername } from '@standardnotes/encryption'
@@ -206,6 +207,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
'identifier',
'defaultHost',
'appVersion',
'apiVersion',
]
for (const optionName of requiredOptions) {
@@ -274,12 +276,12 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
}),
)
const syncEventCallback = async (eventName: SyncEvent) => {
const syncEventCallback = async (eventName: SyncEvent, data?: unknown) => {
const appEvent = applicationEventForSyncEvent(eventName)
if (appEvent) {
await encryptionService.onSyncEvent(eventName)
await this.notifyEvent(appEvent)
await this.notifyEvent(appEvent, data)
if (appEvent === ApplicationEvent.CompletedFullSync) {
if (!this.handledFullSyncStage) {
@@ -534,7 +536,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
return this.addEventObserver(filteredCallback, event)
}
private async notifyEvent(event: ApplicationEvent, data?: ApplicationEventPayload) {
private async notifyEvent(event: ApplicationEvent, data?: unknown) {
if (event === ApplicationEvent.Started) {
this.onStart()
} else if (event === ApplicationEvent.Launched) {
@@ -767,10 +769,11 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
public async register(
email: string,
password: string,
hvmToken: string,
ephemeral = false,
mergeLocal = true,
): Promise<UserRegistrationResponseBody> {
return this.user.register(email, password, ephemeral, mergeLocal)
return this.user.register(email, password, hvmToken, ephemeral, mergeLocal)
}
/**
@@ -784,8 +787,13 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
ephemeral = false,
mergeLocal = true,
awaitSync = false,
hvmToken?: string,
): Promise<HttpResponse<SignInResponse>> {
return this.user.signIn(email, password, strict, ephemeral, mergeLocal, awaitSync)
return this.user.signIn(email, password, strict, ephemeral, mergeLocal, awaitSync, hvmToken)
}
public async getCaptchaUrl(): Promise<HttpResponse<MetaEndpointResponse>> {
return this.legacyApi.getCaptchaUrl()
}
public async changeEmail(
@@ -1090,7 +1090,7 @@ export class Dependencies {
})
this.factory.set(TYPES.AuthApiService, () => {
return new AuthApiService(this.get<AuthServer>(TYPES.AuthServer))
return new AuthApiService(this.get<AuthServer>(TYPES.AuthServer), this.options.apiVersion)
})
this.factory.set(TYPES.AuthManager, () => {
@@ -1432,13 +1432,14 @@ export class Dependencies {
})
this.factory.set(TYPES.SubscriptionApiService, () => {
return new SubscriptionApiService(this.get<SubscriptionServer>(TYPES.SubscriptionServer))
return new SubscriptionApiService(this.get<SubscriptionServer>(TYPES.SubscriptionServer), this.options.apiVersion)
})
this.factory.set(TYPES.UserApiService, () => {
return new UserApiService(
this.get<UserServer>(TYPES.UserServer),
this.get<UserRequestServer>(TYPES.UserRequestServer),
this.options.apiVersion,
)
})
@@ -1542,6 +1543,7 @@ export class Dependencies {
this.options.environment,
this.options.appVersion,
SnjsVersion,
this.options.apiVersion,
this.get<Logger>(TYPES.Logger),
)
})
@@ -166,7 +166,9 @@ describe('SignInWithRecoveryCodes', () => {
})
it('should fail if the sign in with recovery code fails', async () => {
authManager.signInWithRecoveryCodes = jest.fn().mockReturnValue(false)
authManager.signInWithRecoveryCodes = jest.fn().mockReturnValue({
success: false,
})
const useCase = createUseCase()
const result = await useCase.execute({
@@ -68,9 +68,18 @@ export class SignInWithRecoveryCodes implements UseCaseInterface<void> {
recoveryCodes: dto.recoveryCodes,
username: dto.username,
password: rootKey.serverPassword as string,
hvmToken: dto.hvmToken,
})
if (signInResult === false) {
if (signInResult.success === false) {
if (signInResult.captchaURL) {
return Result.fail(
JSON.stringify({
captchaURL: signInResult.captchaURL,
}),
)
}
return Result.fail('Could not sign in with recovery code')
}
@@ -2,4 +2,5 @@ export interface SignInWithRecoveryCodesDTO {
recoveryCodes: string
username: string
password: string
hvmToken?: string
}
+35 -2
View File
@@ -68,6 +68,7 @@ import {
isErrorResponse,
MoveFileResponse,
ValetTokenOperation,
MetaEndpointResponse,
} from '@standardnotes/responses'
import { LegacySession, MapperInterface, Session, SessionToken } from '@standardnotes/domain-core'
import { HttpServiceInterface } from '@standardnotes/api'
@@ -81,7 +82,7 @@ import { Strings } from '@Lib/Strings'
import { AnyFeatureDescription } from '@standardnotes/features'
/** Legacy api version field to be specified in params when calling v0 APIs. */
const V0_API_VERSION = '20200115'
const V0_API_VERSION = '20240226'
type InvalidSessionObserver = (revoked: boolean) => void
@@ -290,6 +291,7 @@ export class LegacyApiService
email: string
serverPassword: string
ephemeral: boolean
hvmToken?: string
}): Promise<HttpResponse<SignInResponse>> {
if (this.authenticating) {
return this.createErrorResponse(API_MESSAGE_LOGIN_IN_PROGRESS, HttpStatusCode.BadRequest)
@@ -301,6 +303,7 @@ export class LegacyApiService
password: dto.serverPassword,
ephemeral: dto.ephemeral,
code_verifier: this.inMemoryStore.getValue(StorageKey.CodeVerifier) as string,
hvm_token: dto.hvmToken,
})
const response = await this.request<SignInResponse>({
@@ -408,7 +411,12 @@ export class LegacyApiService
}
}
async refreshSession(): Promise<HttpResponse<SessionRenewalResponse>> {
/**
* @deprecated
*
* This function should be replaced with @standardnotes/api's `HttpService::refreshSession` function.
*/
async deprecatedRefreshSessionOnlyUsedInE2eTests(): Promise<HttpResponse<SessionRenewalResponse>> {
const preprocessingError = this.preprocessingError()
if (preprocessingError) {
return preprocessingError
@@ -588,6 +596,26 @@ export class LegacyApiService
})
}
async updateSubscriptionSetting(
userUuid: UuidString,
settingName: string,
settingValue: string | null,
sensitive: boolean,
): Promise<HttpResponse<UpdateSettingResponse>> {
const params = {
name: settingName,
value: settingValue,
sensitive: sensitive,
}
return this.tokenRefreshableRequest<UpdateSettingResponse>({
verb: HttpVerb.Put,
url: joinPaths(this.host, Paths.v1.subscriptionSettings(userUuid)),
authentication: this.getSessionAccessToken(),
fallbackErrorMessage: API_MESSAGE_FAILED_UPDATE_SETTINGS,
params,
})
}
async deleteSetting(userUuid: UuidString, settingName: string): Promise<HttpResponse<DeleteSettingResponse>> {
return this.tokenRefreshableRequest<DeleteSettingResponse>({
verb: HttpVerb.Delete,
@@ -933,4 +961,9 @@ export class LegacyApiService
return this.session.accessToken
}
public getCaptchaUrl() {
const response = this.httpService.get<MetaEndpointResponse>(Paths.v1.meta)
return response
}
}
+2
View File
@@ -42,6 +42,7 @@ const SettingsPaths = {
setting: (userUuid: string, settingName: string) => `/v1/users/${userUuid}/settings/${settingName}`,
subscriptionSetting: (userUuid: string, settingName: string) =>
`/v1/users/${userUuid}/subscription-settings/${settingName}`,
subscriptionSettings: (userUuid: string) => `/v1/users/${userUuid}/subscription-settings`,
}
const SubscriptionPaths = {
@@ -69,6 +70,7 @@ export const Paths = {
...SettingsPaths,
...SubscriptionPaths,
...UserPaths,
meta: '/v1/meta',
},
v2: {
...UserPathsV2,
@@ -390,7 +390,20 @@ export class ComponentManager
return this.viewers.find((viewer) => viewer.sessionKey === key)
}
public async toggleTheme(uiFeature: UIFeature<ThemeFeatureDescription>): Promise<void> {
public toggleOtherNonLayerableThemes(uiFeature: UIFeature<ThemeFeatureDescription>): void {
const activeThemes = this.getActiveThemes()
for (const candidate of activeThemes) {
if (candidate.featureIdentifier === uiFeature.featureIdentifier) {
continue
}
if (!candidate.layerable) {
this.removeActiveTheme(candidate)
}
}
}
public async toggleTheme(uiFeature: UIFeature<ThemeFeatureDescription>, skipEntitlementCheck = false): Promise<void> {
this.logger.info('Toggling theme', uiFeature.uniqueIdentifier)
if (this.isThemeActive(uiFeature)) {
@@ -399,7 +412,7 @@ export class ComponentManager
}
const featureStatus = this.features.getFeatureStatus(uiFeature.uniqueIdentifier)
if (featureStatus !== FeatureStatus.Entitled) {
if (!skipEntitlementCheck && featureStatus !== FeatureStatus.Entitled) {
return
}
@@ -410,16 +423,7 @@ export class ComponentManager
if (!uiFeature.layerable) {
await sleep(10)
const activeThemes = this.getActiveThemes()
for (const candidate of activeThemes) {
if (candidate.featureIdentifier === uiFeature.featureIdentifier) {
continue
}
if (!candidate.layerable) {
this.removeActiveTheme(candidate)
}
}
this.toggleOtherNonLayerableThemes(uiFeature)
}
}
@@ -454,7 +458,7 @@ export class ComponentManager
const features: NativeFeatureIdentifier[] = []
const uuids: Uuid[] = []
const strings = this.preferences.getLocalValue(LocalPrefKey.ActiveThemes, [])
const strings = new Set(this.preferences.getLocalValue(LocalPrefKey.ActiveThemes, []))
for (const string of strings) {
const nativeIdentifier = NativeFeatureIdentifier.create(string)
if (!nativeIdentifier.isFailed()) {
@@ -114,8 +114,10 @@ export class GetFeatureStatusUseCase {
}
private isFreeFeature(featureId: NativeFeatureIdentifier) {
return [NativeFeatureIdentifier.TYPES.DarkTheme, NativeFeatureIdentifier.TYPES.PlainEditor].includes(
featureId.value,
)
return [
NativeFeatureIdentifier.TYPES.DarkTheme,
NativeFeatureIdentifier.TYPES.PlainEditor,
NativeFeatureIdentifier.TYPES.ProtonTheme,
].includes(featureId.value)
}
}
@@ -404,7 +404,12 @@ export class SessionManager
return undefined
}
async register(email: string, password: string, ephemeral: boolean): Promise<UserRegistrationResponseBody> {
async register(
email: string,
password: string,
hvmToken: string,
ephemeral: boolean,
): Promise<UserRegistrationResponseBody> {
if (password.length < MINIMUM_PASSWORD_LENGTH) {
throw new ApiCallError(
ErrorMessage.InsufficientPasswordMessage.replace('%LENGTH%', MINIMUM_PASSWORD_LENGTH.toString()),
@@ -429,6 +434,7 @@ export class SessionManager
const registerResponse = await this.userApiService.register({
email,
serverPassword,
hvmToken,
keyParams,
ephemeral,
})
@@ -503,8 +509,9 @@ export class SessionManager
strict = false,
ephemeral = false,
minAllowedVersion?: Common.ProtocolVersion,
hvmToken?: string,
): Promise<SessionManagerResponse> {
const result = await this.performSignIn(email, password, strict, ephemeral, minAllowedVersion)
const result = await this.performSignIn(email, password, strict, ephemeral, minAllowedVersion, hvmToken)
if (
isErrorResponse(result.response) &&
getErrorFromErrorResponse(result.response).tag !== ErrorTag.ClientValidationError &&
@@ -515,7 +522,7 @@ export class SessionManager
/**
* Try signing in with trimmed + lowercase version of email
*/
return this.performSignIn(cleanedEmail, password, strict, ephemeral, minAllowedVersion)
return this.performSignIn(cleanedEmail, password, strict, ephemeral, minAllowedVersion, hvmToken)
} else {
return result
}
@@ -530,6 +537,7 @@ export class SessionManager
strict = false,
ephemeral = false,
minAllowedVersion?: Common.ProtocolVersion,
hvmToken?: string,
): Promise<SessionManagerResponse> {
const paramsResult = await this.retrieveKeyParams({
email,
@@ -593,7 +601,7 @@ export class SessionManager
}
}
const rootKey = await this.encryptionService.computeRootKey(password, keyParams)
const signInResponse = await this.bypassChecksAndSignInWithRootKey(email, rootKey, ephemeral)
const signInResponse = await this.bypassChecksAndSignInWithRootKey(email, rootKey, ephemeral, hvmToken)
return {
response: signInResponse,
@@ -604,6 +612,7 @@ export class SessionManager
email: string,
rootKey: SNRootKey,
ephemeral = false,
hvmToken?: string,
): Promise<HttpResponse<SignInResponse>> {
const { wrappingKey, canceled } = await this.challengeService.getWrappingKeyIfApplicable()
@@ -619,6 +628,7 @@ export class SessionManager
email,
serverPassword: rootKey.serverPassword as string,
ephemeral,
hvmToken,
})
if (!signInResponse.data || isErrorResponse(signInResponse)) {
@@ -874,7 +884,14 @@ export class SessionManager
const willRefreshTokenExpireSoon = refreshTokenExpiration.getTime() - Date.now() < ThirtyMinutes
if (willAccessTokenExpireSoon || willRefreshTokenExpireSoon) {
return this.httpService.refreshSession()
const refreshSessionResultOrError = await this.httpService.refreshSession()
if (refreshSessionResultOrError.isFailed()) {
return false
}
const refreshSessionResult = refreshSessionResultOrError.getValue()
return isErrorResponse(refreshSessionResult)
}
return false
@@ -38,6 +38,10 @@ export class SettingsService extends AbstractService implements SettingsClientIn
return this.provider.getSubscriptionSetting(name)
}
async updateSubscriptionSetting(name: SettingName, payload: string, sensitive = false) {
return this.provider.updateSubscriptionSetting(name, payload, sensitive)
}
async updateSetting(name: SettingName, payload: string, sensitive = false) {
return this.provider.updateSetting(name, payload, sensitive)
}
@@ -77,6 +77,13 @@ export class SettingsGateway {
return response?.data?.setting?.value ?? undefined
}
async updateSubscriptionSetting(name: SettingName, payload: string, sensitive: boolean): Promise<void> {
const response = await this.settingsApi.updateSubscriptionSetting(this.userUuid, name.value, payload, sensitive)
if (isErrorResponse(response)) {
throw new Error(getErrorFromErrorResponse(response).message)
}
}
async getDoesSensitiveSettingExist(name: SettingName): Promise<boolean> {
if (!name.isSensitive()) {
throw new Error(`Setting ${name.value} is not sensitive`)
@@ -2,7 +2,6 @@ import { SettingName } from '@standardnotes/domain-core'
import { SettingData } from '@standardnotes/responses'
import {
MuteSignInEmailsOption,
MuteFailedBackupsEmailsOption,
EmailBackupFrequency,
ListedAuthorSecretsData,
LogSessionUserAgentOption,
@@ -13,7 +12,6 @@ type SettingType =
| EmailBackupFrequency
| ListedAuthorSecretsData
| LogSessionUserAgentOption
| MuteFailedBackupsEmailsOption
| MuteSignInEmailsOption
| MuteMarketingEmailsOption
@@ -21,5 +21,12 @@ export interface SettingsServerInterface {
getSubscriptionSetting(userUuid: UuidString, settingName: string): Promise<HttpResponse<GetSettingResponse>>
updateSubscriptionSetting(
userUuid: UuidString,
settingName: string,
settingValue: string,
sensitive: boolean,
): Promise<HttpResponse<UpdateSettingResponse>>
deleteSetting(userUuid: UuidString, settingName: string): Promise<HttpResponse<DeleteSettingResponse>>
}
+1
View File
@@ -22,6 +22,7 @@ export function createApplicationWithOptions({ identifier, environment, platform
defaultHost: host || Defaults.getDefaultHost(),
appVersion: Defaults.getAppVersion(),
webSocketUrl: Defaults.getDefaultWebSocketUrl(),
apiVersion: ApiVersion.v0,
syncCallsThresholdPerMinute,
})
}
+80 -6
View File
@@ -68,7 +68,7 @@ describe('server session', function () {
password: password,
})
const response = await application.legacyApi.refreshSession()
const response = await application.legacyApi.deprecatedRefreshSessionOnlyUsedInE2eTests()
expect(response.status).to.equal(200)
expect(response.data.session.access_token).to.be.a('string')
@@ -96,8 +96,21 @@ describe('server session', function () {
// After the above sync request is completed, we obtain the session information.
const sessionAfterSync = application.legacyApi.getSession()
/**
* Access token and refresh token values in the new API version (20240226) represent the session uuid.
* So they should stay the same as they were since we are operating on the same session.
*
* The actual token values are stored in cookies indexed by the session uuid and are not accessible to the client.
*
* [E2E][Cookies] When e2e supports the expected behavior, we can uncomment the following lines.
*
*/
// expect(sessionBeforeSync.accessToken.value).to.equal(sessionAfterSync.accessToken.value)
// expect(sessionBeforeSync.refreshToken.value).to.equal(sessionAfterSync.refreshToken.value)
expect(sessionBeforeSync.accessToken.value).to.not.equal(sessionAfterSync.accessToken.value)
expect(sessionBeforeSync.refreshToken.value).to.not.equal(sessionAfterSync.refreshToken.value)
expect(sessionBeforeSync.accessToken.expiresAt).to.be.lessThan(sessionAfterSync.accessToken.expiresAt)
// New token should expire in the future.
expect(sessionAfterSync.accessToken.expiresAt).to.be.greaterThan(Date.now())
@@ -165,7 +178,7 @@ describe('server session', function () {
expect(sessionFromStorage.refreshExpiration).to.equal(sessionFromApiService.refreshToken.expiresAt)
expect(sessionFromStorage.readonlyAccess).to.equal(sessionFromApiService.isReadOnly())
await application.legacyApi.refreshSession()
await application.legacyApi.deprecatedRefreshSessionOnlyUsedInE2eTests()
const updatedSessionFromStorage = await getSessionFromStorage(application)
const updatedSessionFromApiService = application.legacyApi.getSession()
@@ -394,9 +407,15 @@ describe('server session', function () {
await sleepUntilSessionExpires(application, false)
const refreshSessionResponse = await application.legacyApi.refreshSession()
const refreshSessionResponse = await application.legacyApi.deprecatedRefreshSessionOnlyUsedInE2eTests()
expect(refreshSessionResponse.status).to.equal(400)
/**
* [E2E][Cookies] The following expectations are commented out because e2e does not support sending cookies with requests yet.
*/
// expect(refreshSessionResponse.data.error.tag).to.equal('invalid-parameters')
// expect(refreshSessionResponse.data.error.message).to.equal('The provided parameters are not valid.')
expect(refreshSessionResponse.data.error.tag).to.equal('expired-refresh-token')
expect(refreshSessionResponse.data.error.message).to.equal('The refresh token has expired.')
@@ -411,7 +430,11 @@ describe('server session', function () {
expect(syncResponse.data.error.message).to.equal('Invalid login credentials.')
}).timeout(Factory.TwentySecondTimeout)
it('should fail when renewing a session with an invalid refresh token', async function () {
/**
* This test is skipped due to the fact that tokens reside now in cookies and are not accessible to the client.
* Thus it is not possible to tamper with the refresh token.
*/
it.skip('should fail when renewing a session with an invalid refresh token', async function () {
await Factory.registerUserToApplication({
application: application,
email: email,
@@ -429,7 +452,7 @@ describe('server session', function () {
})
application.sessions.initializeFromDisk()
const refreshSessionResponse = await application.legacyApi.refreshSession()
const refreshSessionResponse = await application.legacyApi.deprecatedRefreshSessionOnlyUsedInE2eTests()
expect(refreshSessionResponse.status).to.equal(400)
expect(refreshSessionResponse.data.error.tag).to.equal('invalid-refresh-token')
@@ -447,7 +470,7 @@ describe('server session', function () {
password: password,
})
const refreshPromise = application.legacyApi.refreshSession()
const refreshPromise = application.legacyApi.deprecatedRefreshSessionOnlyUsedInE2eTests()
const syncResponse = await application.legacyApi.sync([])
expect(syncResponse.data.error).to.be.ok
@@ -458,6 +481,57 @@ describe('server session', function () {
await refreshPromise
})
it('should tell the client to refresh the token if one is used during the cooldown period after a refresh', async function () {
await Factory.registerUserToApplication({
application: application,
email: email,
password: password,
})
const mimickApplyingSessionFromTheServerUnsuccessfully = () => {}
const originalSetSessionFn = application.http.setSession
const originalRefreshSessionCallbackFn = application.http.refreshSessionCallback
application.http.setSession = mimickApplyingSessionFromTheServerUnsuccessfully
application.http.refreshSessionCallback = mimickApplyingSessionFromTheServerUnsuccessfully
const refreshResultOrError = await application.http.refreshSession()
expect(refreshResultOrError.isFailed()).to.equal(false)
const refreshResult = refreshResultOrError.getValue()
expect(isErrorResponse(refreshResult)).to.equal(false)
const secondRefreshResultOrErrorWithNotAppliedSession = await application.http.refreshSession()
expect(secondRefreshResultOrErrorWithNotAppliedSession.isFailed()).to.equal(false)
const secondRefreshResultWithNotAppliedSession = secondRefreshResultOrErrorWithNotAppliedSession.getValue()
expect(isErrorResponse(secondRefreshResultWithNotAppliedSession)).to.equal(false)
application.http.setSession = originalSetSessionFn
application.http.refreshSessionCallback = originalRefreshSessionCallbackFn
})
it('if session renewal response is dropped, next sync with server should return a 498 and successfully renew the session', async function () {
await Factory.registerUserToApplication({
application: application,
email: email,
password: password,
})
await sleepUntilSessionExpires(application)
const refreshSpy = sinon.spy(application.http, 'refreshSession')
/**
* With this sync, we expect refreshSession to be called twice, once where the response is dropped,
* and the other time where the request succeeds
*/
application.http.__simulateNextSessionRefreshResponseDrop = true
await application.sync.sync(syncOptions)
await application.sync.sync(syncOptions)
expect(refreshSpy.callCount).to.equal(2)
})
it('notes should be synced as expected after refreshing a session', async function () {
await Factory.registerUserToApplication({
application: application,
+4 -4
View File
@@ -123,12 +123,12 @@ describe('settings service', function () {
true,
)
await application.settings.updateSetting(
SettingName.create(SettingName.NAMES.MuteFailedBackupsEmails).getValue(),
MuteFailedBackupsEmailsOption.Muted,
SettingName.create(SettingName.NAMES.LogSessionUserAgent).getValue(),
LogSessionUserAgentOption.Enabled,
)
const settings = await application.settings.listSettings()
expect(settings.getSettingValue(SettingName.create(SettingName.NAMES.MuteFailedBackupsEmails).getValue())).to.eql(
MuteFailedBackupsEmailsOption.Muted,
expect(settings.getSettingValue(SettingName.create(SettingName.NAMES.LogSessionUserAgent).getValue())).to.eql(
LogSessionUserAgentOption.Enabled,
)
expect(settings.getSettingValue(SettingName.create(SettingName.NAMES.MfaSecret).getValue())).to.not.be.ok
})
+1 -1
View File
@@ -10,7 +10,7 @@
<script src="https://unpkg.com/[email protected]/mocha.js"></script>
<script src="https://unpkg.com/[email protected]/lib/chai-subset.js"></script>
<script src="https://unpkg.com/[email protected]/pkg/sinon.js"></script>
<script src="./vendor/sncrypto-web.js"></script>
<script src="https://unpkg.com/@standardnotes/[email protected]/dist/sncrypto-web.js"></script>
<script src="../dist/snjs.js"></script>
<script type="module">
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/snjs",
"version": "2.208.6",
"version": "2.208.18",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+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.8.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-13)
**Note:** Version bump only for package @standardnotes/styles
## [1.8.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-24)
**Note:** Version bump only for package @standardnotes/styles
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/styles",
"version": "1.8.1",
"version": "1.8.2",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"publishConfig": {
@@ -45,3 +45,10 @@
scrollbar-width: thin;
}
.windows-web,
.windows-desktop {
.md\:hover\:overflow-y-auto {
scrollbar-gutter: stable;
}
}
+40
View File
@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.37.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.37.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.37.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.37.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)
### Bug Fixes
* Fixed issue with system color scheme on mobile ([45ca99c](https://github.com/standardnotes/app/commit/45ca99c627e51b0b6b0b55e211788fa4cb0f1c70))
## [1.37.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
### Bug Fixes
* Fixed issue with system color scheme not being applied correctly on start ([7967dde](https://github.com/standardnotes/app/commit/7967ddead790d89478554cd6a96429fd06958590))
## [1.37.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.37.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-13)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.37.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.37.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.37.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-02-22)
**Note:** Version bump only for package @standardnotes/ui-services
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/ui-services",
"version": "1.37.1",
"version": "1.37.10",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+41 -10
View File
@@ -27,7 +27,9 @@ const DefaultThemeIdentifier = 'Default'
export class ThemeManager extends AbstractUIService {
private themesActiveInTheUI: ActiveThemeList
private lastUseDeviceThemeSettings = false
private lastUseDeviceThemeSettings: boolean | undefined
private lastAutoLightTheme: string | undefined
private lastAutoDarkTheme: string | undefined
constructor(
application: WebApplicationInterface,
@@ -89,7 +91,7 @@ export class ThemeManager extends AbstractUIService {
break
}
case ApplicationEvent.FeaturesAvailabilityChanged: {
this.handleFeaturesAvailabilityChanged()
this.handleFeaturesAvailabilityChanged().catch(console.error)
break
}
case ApplicationEvent.Launched: {
@@ -166,15 +168,25 @@ export class ThemeManager extends AbstractUIService {
this.toggleTranslucentUIColors()
const useDeviceThemeSettings = this.preferences.getLocalValue(LocalPrefKey.UseSystemColorScheme, false)
const useSystemColorScheme = this.preferences.getLocalValue(LocalPrefKey.UseSystemColorScheme, false)
const autoLightTheme = this.preferences.getLocalValue(LocalPrefKey.AutoLightThemeIdentifier, DefaultThemeIdentifier)
const autoDarkTheme = this.preferences.getLocalValue(
LocalPrefKey.AutoDarkThemeIdentifier,
NativeFeatureIdentifier.TYPES.DarkTheme,
)
const hasPreferenceChanged = useDeviceThemeSettings !== this.lastUseDeviceThemeSettings
const hasPreferenceChanged =
useSystemColorScheme !== this.lastUseDeviceThemeSettings ||
autoLightTheme !== this.lastAutoLightTheme ||
autoDarkTheme !== this.lastAutoDarkTheme
if (hasPreferenceChanged) {
this.lastUseDeviceThemeSettings = useDeviceThemeSettings
this.lastUseDeviceThemeSettings = useSystemColorScheme
this.lastAutoLightTheme = autoLightTheme
this.lastAutoDarkTheme = autoDarkTheme
}
if (hasPreferenceChanged && useDeviceThemeSettings) {
if (hasPreferenceChanged && useSystemColorScheme) {
let prefersDarkColorScheme = window.matchMedia('(prefers-color-scheme: dark)').matches
if (this.application.isNativeMobileWeb()) {
@@ -185,7 +197,7 @@ export class ThemeManager extends AbstractUIService {
}
}
private handleFeaturesAvailabilityChanged(): void {
private async handleFeaturesAvailabilityChanged() {
let hasChange = false
for (const theme of this.themesActiveInTheUI.asThemes()) {
@@ -205,6 +217,15 @@ export class ThemeManager extends AbstractUIService {
}
}
const shouldSetThemeAsPerColorScheme = this.preferences.getLocalValue(LocalPrefKey.UseSystemColorScheme, false)
if (shouldSetThemeAsPerColorScheme) {
let prefersDarkColorScheme = window.matchMedia('(prefers-color-scheme: dark)').matches
if (this.application.isNativeMobileWeb()) {
prefersDarkColorScheme = (await this.application.mobileDevice.getColorScheme()) === 'dark'
}
hasChange = this.setThemeAsPerColorScheme(prefersDarkColorScheme)
}
if (hasChange) {
void this.cacheThemeState()
}
@@ -218,7 +239,9 @@ export class ThemeManager extends AbstractUIService {
}
}
private setThemeAsPerColorScheme(prefersDarkColorScheme: boolean) {
private setThemeAsPerColorScheme(prefersDarkColorScheme: boolean): boolean {
let didChangeTheme = false
const preference = prefersDarkColorScheme
? LocalPrefKey.AutoDarkThemeIdentifier
: LocalPrefKey.AutoLightThemeIdentifier
@@ -239,6 +262,7 @@ export class ThemeManager extends AbstractUIService {
const toggleActiveTheme = () => {
if (activeTheme) {
void this.components.toggleTheme(activeTheme)
didChangeTheme = true
}
}
@@ -246,10 +270,17 @@ export class ThemeManager extends AbstractUIService {
toggleActiveTheme()
} else {
const theme = themes.find((theme) => theme.featureIdentifier === themeIdentifier)
if (theme && !this.components.isThemeActive(theme)) {
this.components.toggleTheme(theme).catch(console.error)
if (theme) {
if (!this.components.isThemeActive(theme)) {
this.components.toggleTheme(theme, true).catch(console.error)
} else {
this.components.toggleOtherNonLayerableThemes(theme)
}
didChangeTheme = true
}
}
return didChangeTheme
}
private async activateCachedThemes() {
+116
View File
@@ -3,6 +3,122 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.192.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/web
## [3.192.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)
**Note:** Version bump only for package @standardnotes/web
## [3.192.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)
**Note:** Version bump only for package @standardnotes/web
## [3.192.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-04)
**Note:** Version bump only for package @standardnotes/web
## [3.192.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-01)
### Bug Fixes
* Fixed super note "Table of contents" not working on mobile ([73eba38](https://github.com/standardnotes/app/commit/73eba38c1444e85839d771fb297e3035eabd99c8))
## [3.192.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-28)
**Note:** Version bump only for package @standardnotes/web
## [3.192.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-27)
**Note:** Version bump only for package @standardnotes/web
## [3.192.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)
**Note:** Version bump only for package @standardnotes/web
## [3.192.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)
**Note:** Version bump only for package @standardnotes/web
## [3.192.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/web
## [3.192.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/web
## [3.192.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)
**Note:** Version bump only for package @standardnotes/web
## [3.192.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
### Reverts
* Revert "feat: Markdown text is now parsed correctly when pasted" ([bb81c8a](https://github.com/standardnotes/app/commit/bb81c8acfc470df76a70ab74fa8d487216e2d190))
# [3.192.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/web
## [3.191.24](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)
**Note:** Version bump only for package @standardnotes/web
## [3.191.23](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-13)
**Note:** Version bump only for package @standardnotes/web
## [3.191.22](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-12)
**Note:** Version bump only for package @standardnotes/web
## [3.191.21](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
### Bug Fixes
* Fixed issue with re-authentication prompts ([6d872cd](https://github.com/standardnotes/app/commit/6d872cd45a504c824d6fa2d3325e1ba2401f3046))
## [3.191.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/web
## [3.191.19](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)
**Note:** Version bump only for package @standardnotes/web
## [3.191.18](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-08)
**Note:** Version bump only for package @standardnotes/web
## [3.191.17](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
### Bug Fixes
* Fixed issue with re-authentication prompts ([#2858](https://github.com/standardnotes/app/issues/2858)) [skip e2e] ([3b2f761](https://github.com/standardnotes/app/commit/3b2f76166126a5b11f35b64aacefa37618622c3d))
## [3.191.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)
**Note:** Version bump only for package @standardnotes/web
## [3.191.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-06)
**Note:** Version bump only for package @standardnotes/web
## [3.191.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/web
## [3.191.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)
**Note:** Version bump only for package @standardnotes/web
## [3.191.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)
**Note:** Version bump only for package @standardnotes/web
## [3.191.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)
**Note:** Version bump only for package @standardnotes/web
+309
View File
@@ -1,5 +1,314 @@
{
"versions": [
{
"version": "3.192.15",
"title": "[3.192.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.192.14",
"title": "[3.192.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-10)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.192.13",
"title": "[3.192.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-08)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.192.10",
"title": "[3.192.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-04)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.192.9",
"title": "[3.192.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-04-01)",
"date": null,
"body": "### Bug Fixes\n\n* Fixed super note \"Table of contents\" not working on mobile ([73eba38](https://github.com/standardnotes/app/commit/73eba38c1444e85839d771fb297e3035eabd99c8))",
"parsed": {
"_": [
"Fixed super note \"Table of contents\" not working on mobile (73eba38)"
],
"Bug Fixes": [
"Fixed super note \"Table of contents\" not working on mobile (73eba38)"
]
}
},
{
"version": "3.192.8",
"title": "[3.192.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-28)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.192.7",
"title": "[3.192.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-27)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.192.6",
"title": "[3.192.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.192.5",
"title": "[3.192.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-26)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.192.4",
"title": "[3.192.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.192.3",
"title": "[3.192.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.192.2",
"title": "[3.192.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-22)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.192.1",
"title": "[3.192.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)",
"date": null,
"body": "### Reverts\n\n* Revert \"feat: Markdown text is now parsed correctly when pasted\" ([bb81c8a](https://github.com/standardnotes/app/commit/bb81c8acfc470df76a70ab74fa8d487216e2d190))",
"parsed": {
"_": [
"Revert \"feat: Markdown text is now parsed correctly when pasted\" (bb81c8a)"
],
"Reverts": [
"Revert \"feat: Markdown text is now parsed correctly when pasted\" (bb81c8a)"
]
}
},
{
"version": "3.192.0",
"title": "[3.192.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.191.24",
"title": "[3.191.24](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-14)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.191.23",
"title": "[3.191.23](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-13)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.191.22",
"title": "[3.191.22](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-12)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.191.21",
"title": "[3.191.21](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)",
"date": null,
"body": "### Bug Fixes\n\n* Fixed issue with re-authentication prompts ([6d872cd](https://github.com/standardnotes/app/commit/6d872cd45a504c824d6fa2d3325e1ba2401f3046))",
"parsed": {
"_": [
"Fixed issue with re-authentication prompts (6d872cd)"
],
"Bug Fixes": [
"Fixed issue with re-authentication prompts (6d872cd)"
]
}
},
{
"version": "3.191.20",
"title": "[3.191.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.191.19",
"title": "[3.191.19](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-11)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.191.18",
"title": "[3.191.18](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-08)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.191.17",
"title": "[3.191.17](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)",
"date": null,
"body": "### Bug Fixes\n\n* Fixed issue with re-authentication prompts ([#2858](https://github.com/standardnotes/app/issues/2858)) [skip e2e] ([3b2f761](https://github.com/standardnotes/app/commit/3b2f76166126a5b11f35b64aacefa37618622c3d))",
"parsed": {
"_": [
"Fixed issue with re-authentication prompts (#2858) skip e2e] ([3b2f761)"
],
"Bug Fixes": [
"Fixed issue with re-authentication prompts (#2858) skip e2e] ([3b2f761)"
]
}
},
{
"version": "3.191.16",
"title": "[3.191.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-07)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.191.15",
"title": "[3.191.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-06)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.191.14",
"title": "[3.191.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.191.13",
"title": "[3.191.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-05)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.191.12",
"title": "[3.191.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.191.11",
"title": "[3.191.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2024-03-01)",
+4
View File
@@ -0,0 +1,4 @@
FROM nginx:alpine
COPY ./dist /usr/share/nginx/html
+5 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/web",
"version": "3.191.11",
"version": "3.192.15",
"license": "AGPL-3.0",
"main": "dist/app.js",
"author": "Standard Notes",
@@ -110,6 +110,10 @@
"dependencies": {
"@ariakit/react": "^0.3.9",
"@lexical/headless": "0.13.1",
"@lexical/link": "0.13.1",
"@lexical/list": "0.13.1",
"@lexical/rich-text": "0.13.1",
"@lexical/utils": "0.13.1",
"@radix-ui/react-slot": "^1.0.1",
"@react-pdf/renderer": "^3.3.2",
"comlink": "^4.4.1",
@@ -0,0 +1,50 @@
:root {
--background-norm: #16141c;
--background-weak: #292733;
--background-strong: #3f3b4c;
--text-norm: #ffffff;
--text-weak: #a7a4b5;
--border-norm: #4a4658;
--border-weak: #343140;
--primary: #8a6eff;
--interaction-norm: #6d4aff;
--sn-stylekit-background-color: var(--background-norm);
--sn-stylekit-foreground-color: var(--text-norm);
--sn-stylekit-border-color: var(--border-weak);
--sn-stylekit-contrast-background-color: var(--background-weak);
--sn-stylekit-contrast-foreground-color: var(--text-norm);
--sn-stylekit-contrast-border-color: var(--border-norm);
--sn-stylekit-secondary-background-color: var(--background-weak);
--sn-stylekit-secondary-foreground-color: var(--text-norm);
--sn-stylekit-info-color: var(--interaction-norm);
--sn-stylekit-info-backdrop-color: #6e4aff0f;
--sn-stylekit-passive-color-0: var(--text-weak);
--sn-stylekit-passive-color-3: var(--background-strong);
--sn-stylekit-passive-color-4: #3f3b4c;
--sn-stylekit-passive-color-5: var(--background-weak);
--navigation-item-selected-background-color: var(--background-strong);
--sn-stylekit-paragraph-text-color: var(--text-weak);
--sn-stylekit-scrollbar-thumb-color: var(--primary);
}
a,
.Lexical__link,
.Lexical__textCode {
color: var(--primary);
}
.Collapsible__container,
.Lexical__tableCellHeader {
border-color: var(--border-norm);
}
.Lexical__quote {
color: var(--text-weak);
}
#blocks-editor hr.selected {
outline-color: var(--primary);
}
@@ -23,6 +23,7 @@ import {
SNNote,
DesktopManagerInterface,
FileItem,
ApiVersion,
} from '@standardnotes/snjs'
import { action, computed, makeObservable, observable } from 'mobx'
import { startAuthentication, startRegistration } from '@simplewebauthn/browser'
@@ -112,6 +113,10 @@ export class WebApplication extends SNApplication implements WebApplicationInter
defaultHost: defaultSyncServerHost,
appVersion: deviceInterface.appVersion,
webSocketUrl: webSocketUrl,
/**
* iOS file:// based origin does not work with production cookies
*/
apiVersion: platform === Platform.Ios || platform === Platform.Android ? ApiVersion.v0 : ApiVersion.v1,
loadBatchSize:
deviceInterface.environment === Environment.Mobile ? 250 : ApplicationOptionsDefaults.loadBatchSize,
sleepBetweenBatches:
@@ -16,6 +16,8 @@ import DecoratedPasswordInput from '@/Components/Input/DecoratedPasswordInput'
import Icon from '@/Components/Icon/Icon'
import IconButton from '@/Components/Button/IconButton'
import { useApplication } from '../ApplicationProvider'
import { useCaptcha } from '@/Hooks/useCaptcha'
import { isErrorResponse } from '@standardnotes/snjs'
type Props = {
setMenuPane: (pane: AccountMenuPane) => void
@@ -33,6 +35,39 @@ const ConfirmPassword: FunctionComponent<Props> = ({ setMenuPane, email, passwor
const [shouldMergeLocal, setShouldMergeLocal] = useState(true)
const [error, setError] = useState('')
const [hvmToken, setHVMToken] = useState('')
const [captchaURL, setCaptchaURL] = useState('')
const register = useCallback(() => {
setIsRegistering(true)
application
.register(email, password, hvmToken, isEphemeral, shouldMergeLocal)
.then(() => {
application.accountMenuController.closeAccountMenu()
application.accountMenuController.setCurrentPane(AccountMenuPane.GeneralMenu)
})
.catch((err) => {
console.error(err)
setError(err.message)
})
.finally(() => {
setIsRegistering(false)
})
}, [application, email, hvmToken, isEphemeral, password, shouldMergeLocal])
const captchaIframe = useCaptcha(captchaURL, (token) => {
setHVMToken(token)
setCaptchaURL('')
})
useEffect(() => {
if (!hvmToken) {
return
}
register()
}, [hvmToken, register])
const passwordInputRef = useRef<HTMLInputElement>(null)
useEffect(() => {
@@ -51,6 +86,28 @@ const ConfirmPassword: FunctionComponent<Props> = ({ setMenuPane, email, passwor
setShouldMergeLocal(!shouldMergeLocal)
}, [shouldMergeLocal])
const checkIfCaptchaRequiredAndRegister = useCallback(() => {
application
.getCaptchaUrl()
.then((response) => {
if (isErrorResponse(response)) {
throw new Error()
}
const { captchaUIUrl } = response.data
if (captchaUIUrl) {
setCaptchaURL(captchaUIUrl)
} else {
setCaptchaURL('')
register()
}
})
.catch((error) => {
console.error(error)
setCaptchaURL('')
register()
})
}, [application, register])
const handleConfirmFormSubmit: FormEventHandler = useCallback(
(e) => {
e.preventDefault()
@@ -60,28 +117,16 @@ const ConfirmPassword: FunctionComponent<Props> = ({ setMenuPane, email, passwor
return
}
if (password === confirmPassword) {
setIsRegistering(true)
application
.register(email, password, isEphemeral, shouldMergeLocal)
.then(() => {
application.accountMenuController.closeAccountMenu()
application.accountMenuController.setCurrentPane(AccountMenuPane.GeneralMenu)
})
.catch((err) => {
console.error(err)
setError(err.message)
})
.finally(() => {
setIsRegistering(false)
})
} else {
if (password !== confirmPassword) {
setError(STRING_NON_MATCHING_PASSWORDS)
setConfirmPassword('')
passwordInputRef.current?.focus()
return
}
checkIfCaptchaRequiredAndRegister()
},
[application, confirmPassword, email, isEphemeral, password, shouldMergeLocal],
[checkIfCaptchaRequiredAndRegister, confirmPassword, password],
)
const handleKeyDown: KeyboardEventHandler = useCallback(
@@ -100,35 +145,26 @@ const ConfirmPassword: FunctionComponent<Props> = ({ setMenuPane, email, passwor
setMenuPane(AccountMenuPane.Register)
}, [setMenuPane])
return (
const confirmPasswordForm = (
<>
<div className="mb-3 mt-1 flex items-center px-3">
<IconButton
icon="arrow-left"
title="Go back"
className="mr-2 flex p-0 text-neutral"
onClick={handleGoBack}
focusable={true}
disabled={isRegistering}
/>
<div className="text-base font-bold">Confirm password</div>
</div>
<div className="mb-3 px-3 text-sm">
Because your notes are encrypted using your password,{' '}
<span className="text-danger">Standard Notes does not have a password reset option</span>. If you forget your
password, you will permanently lose access to your data.
</div>
<form onSubmit={handleConfirmFormSubmit} className="mb-1 px-3">
<DecoratedPasswordInput
className={{ container: 'mb-2' }}
disabled={isRegistering}
left={[<Icon type="password" className="text-neutral" />]}
onChange={handlePasswordChange}
onKeyDown={handleKeyDown}
placeholder="Confirm password"
ref={passwordInputRef}
value={confirmPassword}
/>
{!isRegistering && (
<DecoratedPasswordInput
className={{ container: 'mb-2' }}
disabled={isRegistering}
left={[<Icon type="password" className="text-neutral" />]}
onChange={handlePasswordChange}
onKeyDown={handleKeyDown}
placeholder="Confirm password"
ref={passwordInputRef}
value={confirmPassword}
/>
)}
{error ? <div className="my-2 text-danger">{error}</div> : null}
<Button
primary
@@ -157,6 +193,23 @@ const ConfirmPassword: FunctionComponent<Props> = ({ setMenuPane, email, passwor
</form>
</>
)
return (
<>
<div className="mb-3 mt-1 flex items-center px-3">
<IconButton
icon="arrow-left"
title="Go back"
className="mr-2 flex p-0 text-neutral"
onClick={handleGoBack}
focusable={true}
disabled={isRegistering}
/>
<div className="text-base font-bold">{captchaURL ? 'Human verification' : 'Confirm password'}</div>
</div>
{captchaURL ? <div className="p-[10px]">{captchaIframe}</div> : confirmPasswordForm}
</>
)
}
export default observer(ConfirmPassword)
@@ -10,8 +10,9 @@ import Icon from '@/Components/Icon/Icon'
import IconButton from '@/Components/Button/IconButton'
import AdvancedOptions from './AdvancedOptions'
import HorizontalSeparator from '../Shared/HorizontalSeparator'
import { getErrorFromErrorResponse, isErrorResponse } from '@standardnotes/snjs'
import { getErrorFromErrorResponse, isErrorResponse, getCaptchaHeader } from '@standardnotes/snjs'
import { useApplication } from '../ApplicationProvider'
import { useCaptcha } from '@/Hooks/useCaptcha'
type Props = {
setMenuPane: (pane: AccountMenuPane) => void
@@ -34,6 +35,15 @@ const SignInPane: FunctionComponent<Props> = ({ setMenuPane }) => {
const [isRecoverySignIn, setIsRecoverySignIn] = useState(false)
const [captchaURL, setCaptchaURL] = useState('')
const [showCaptcha, setShowCaptcha] = useState(false)
const [hvmToken, setHVMToken] = useState('')
const captchaIframe = useCaptcha(captchaURL, (token) => {
setHVMToken(token)
setShowCaptcha(false)
setCaptchaURL('')
})
const emailInputRef = useRef<HTMLInputElement>(null)
const passwordInputRef = useRef<HTMLInputElement>(null)
@@ -95,8 +105,12 @@ const SignInPane: FunctionComponent<Props> = ({ setMenuPane }) => {
passwordInputRef?.current?.blur()
application
.signIn(email, password, isStrictSignin, isEphemeral, shouldMergeLocal)
.signIn(email, password, isStrictSignin, isEphemeral, shouldMergeLocal, false, hvmToken)
.then((response) => {
const captchaURL = getCaptchaHeader(response)
if (captchaURL) {
setCaptchaURL(captchaURL)
}
if (isErrorResponse(response)) {
throw new Error(getErrorFromErrorResponse(response).message)
}
@@ -106,12 +120,13 @@ const SignInPane: FunctionComponent<Props> = ({ setMenuPane }) => {
console.error(err)
setError(err.message ?? err.toString())
setPassword('')
setHVMToken('')
passwordInputRef?.current?.blur()
})
.finally(() => {
setIsSigningIn(false)
})
}, [application, email, isEphemeral, isStrictSignin, password, shouldMergeLocal])
}, [application, email, hvmToken, isEphemeral, isStrictSignin, password, shouldMergeLocal])
const recoverySignIn = useCallback(() => {
setIsSigningIn(true)
@@ -123,10 +138,21 @@ const SignInPane: FunctionComponent<Props> = ({ setMenuPane }) => {
recoveryCodes,
username: email,
password: password,
hvmToken,
})
.then((result) => {
if (result.isFailed()) {
throw new Error(result.getError())
const error = result.getError()
try {
const parsed = JSON.parse(error)
if (parsed.captchaURL) {
setCaptchaURL(parsed.captchaURL)
return
}
} catch (e) {
setCaptchaURL('')
}
throw new Error(error)
}
application.accountMenuController.closeAccountMenu()
})
@@ -134,12 +160,13 @@ const SignInPane: FunctionComponent<Props> = ({ setMenuPane }) => {
console.error(err)
setError(err.message ?? err.toString())
setPassword('')
setHVMToken('')
passwordInputRef?.current?.blur()
})
.finally(() => {
setIsSigningIn(false)
})
}, [application, email, password, recoveryCodes])
}, [application.accountMenuController, application.signInWithRecoveryCodes, email, hvmToken, password, recoveryCodes])
const onPrivateUsernameChange = useCallback(
(newisPrivateUsername: boolean, privateUsernameIdentifier?: string) => {
@@ -151,28 +178,37 @@ const SignInPane: FunctionComponent<Props> = ({ setMenuPane }) => {
[setEmail],
)
const performSignIn = useCallback(() => {
if (!email || email.length === 0) {
emailInputRef?.current?.focus()
return
}
if (!password || password.length === 0) {
passwordInputRef?.current?.focus()
return
}
if (isRecoverySignIn) {
recoverySignIn()
return
}
signIn()
}, [email, isRecoverySignIn, password, recoverySignIn, signIn])
const handleSignInFormSubmit = useCallback(
(e: React.SyntheticEvent) => {
e.preventDefault()
if (!email || email.length === 0) {
emailInputRef?.current?.focus()
if (captchaURL) {
setShowCaptcha(true)
return
}
if (!password || password.length === 0) {
passwordInputRef?.current?.focus()
return
}
if (isRecoverySignIn) {
recoverySignIn()
return
}
signIn()
performSignIn()
},
[email, password, isRecoverySignIn, signIn, recoverySignIn],
[captchaURL, performSignIn],
)
const handleKeyDown: KeyboardEventHandler = useCallback(
@@ -184,19 +220,16 @@ const SignInPane: FunctionComponent<Props> = ({ setMenuPane }) => {
[handleSignInFormSubmit],
)
return (
useEffect(() => {
if (!hvmToken) {
return
}
performSignIn()
}, [hvmToken, performSignIn])
const signInForm = (
<>
<div className="mb-3 mt-1 flex items-center px-3">
<IconButton
icon="arrow-left"
title="Go back"
className="mr-2 flex p-0 text-neutral"
onClick={() => setMenuPane(AccountMenuPane.GeneralMenu)}
focusable={true}
disabled={isSigningIn}
/>
<div className="text-base font-bold">Sign in</div>
</div>
<div className="mb-1 px-3">
<DecoratedInput
className={{ container: `mb-2 ${error ? 'border-danger' : null}` }}
@@ -257,6 +290,23 @@ const SignInPane: FunctionComponent<Props> = ({ setMenuPane }) => {
/>
</>
)
return (
<>
<div className="mb-3 mt-1 flex items-center px-3">
<IconButton
icon="arrow-left"
title="Go back"
className="mr-2 flex p-0 text-neutral"
onClick={() => setMenuPane(AccountMenuPane.GeneralMenu)}
focusable={true}
disabled={isSigningIn}
/>
<div className="text-base font-bold">{showCaptcha ? 'Human verification' : 'Sign in'}</div>
</div>
{showCaptcha ? <div className="p-[10px]">{captchaIframe}</div> : signInForm}
</>
)
}
export default observer(SignInPane)
@@ -1,6 +1,13 @@
import { WebApplicationGroup } from '@/Application/WebApplicationGroup'
import { getPlatformString } from '@/Utils'
import { ApplicationEvent, Challenge, removeFromArray, WebAppEvent } from '@standardnotes/snjs'
import {
ApplicationEvent,
Challenge,
getErrorMessageFromErrorResponseBody,
HttpErrorResponseBody,
removeFromArray,
WebAppEvent,
} from '@standardnotes/snjs'
import { alertDialog, isIOS, RouteType } from '@standardnotes/ui-services'
import { WebApplication } from '@/Application/WebApplication'
import Footer from '@/Components/Footer/Footer'
@@ -117,7 +124,7 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
onAppLaunch()
}
const removeAppObserver = application.addEventObserver(async (eventName) => {
const removeAppObserver = application.addEventObserver(async (eventName, data?: unknown) => {
if (eventName === ApplicationEvent.Started) {
onAppStart()
} else if (eventName === ApplicationEvent.Launched) {
@@ -147,6 +154,14 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
type: ToastType.Error,
message: 'Too many requests. Please try again later.',
})
} else if (eventName === ApplicationEvent.FailedSync) {
addToast({
type: ToastType.Error,
message: getErrorMessageFromErrorResponseBody(
data as HttpErrorResponseBody,
'Sync error. Please try again later.',
),
})
}
})
@@ -23,12 +23,15 @@ const QuickSettingsButton = ({ application, isMobileNavigation = false }: Props)
const toggleMenu = () => setIsOpen(!isOpen)
useEffect(() => {
const darkThemeFeature = new UIFeature(GetDarkThemeFeature())
return commandService.addCommandHandler({
command: TOGGLE_DARK_MODE_COMMAND,
category: 'General',
description: 'Toggle dark mode',
onKeyDown: () => {
void application.componentManager.toggleTheme(new UIFeature(GetDarkThemeFeature()))
void application.componentManager.toggleTheme(darkThemeFeature)
return true
},
})
}, [application, commandService])
@@ -42,6 +42,16 @@ const Email: FunctionComponent<Props> = ({ application }: Props) => {
}
}
const updateSubscriptionSetting = async (settingName: SettingName, payload: string): Promise<boolean> => {
try {
await application.settings.updateSubscriptionSetting(settingName, payload, false)
return true
} catch (e) {
application.alerts.alert(STRING_FAILED_TO_UPDATE_USER_SETTING).catch(console.error)
return false
}
}
const loadSettings = useCallback(async () => {
if (!application.sessions.getUser()) {
return
@@ -79,7 +89,7 @@ const Email: FunctionComponent<Props> = ({ application }: Props) => {
previousValue === MuteSignInEmailsOption.Muted ? MuteSignInEmailsOption.NotMuted : MuteSignInEmailsOption.Muted
setSignInEmailsMutedValue(newValue)
const updateResult = await updateSetting(
const updateResult = await updateSubscriptionSetting(
SettingName.create(SettingName.NAMES.MuteSignInEmails).getValue(),
newValue,
)
@@ -1,4 +1,4 @@
import { convertStringifiedBooleanToBoolean, isDesktopApplication } from '@/Utils'
import { isDesktopApplication } from '@/Utils'
import { STRING_FAILED_TO_UPDATE_USER_SETTING } from '@/Constants/Strings'
import { useCallback, useEffect, useState } from 'react'
import { WebApplication } from '@/Application/WebApplication'
@@ -6,9 +6,7 @@ import { observer } from 'mobx-react-lite'
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
import Dropdown from '@/Components/Dropdown/Dropdown'
import { DropdownItem } from '@/Components/Dropdown/DropdownItem'
import Switch from '@/Components/Switch/Switch'
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import { EmailBackupFrequency, MuteFailedBackupsEmailsOption, SettingName } from '@standardnotes/snjs'
import { EmailBackupFrequency, SettingName } from '@standardnotes/snjs'
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
import Spinner from '@/Components/Spinner/Spinner'
@@ -21,7 +19,6 @@ const EmailBackups = ({ application }: Props) => {
const [isLoading, setIsLoading] = useState(false)
const [emailFrequency, setEmailFrequency] = useState<EmailBackupFrequency>(EmailBackupFrequency.Disabled)
const [emailFrequencyOptions, setEmailFrequencyOptions] = useState<DropdownItem[]>([])
const [isFailedBackupEmailMuted, setIsFailedBackupEmailMuted] = useState(true)
const hasAccount = application.hasAccount()
const loadEmailFrequencySetting = useCallback(async () => {
@@ -38,14 +35,6 @@ const EmailBackups = ({ application }: Props) => {
EmailBackupFrequency.Disabled,
),
)
setIsFailedBackupEmailMuted(
convertStringifiedBooleanToBoolean(
userSettings.getSettingValue<MuteFailedBackupsEmailsOption>(
SettingName.create(SettingName.NAMES.MuteFailedBackupsEmails).getValue(),
MuteFailedBackupsEmailsOption.NotMuted,
),
),
)
} catch (error) {
console.error(error)
} finally {
@@ -90,19 +79,6 @@ const EmailBackups = ({ application }: Props) => {
}
}
const toggleMuteFailedBackupEmails = async () => {
const previousValue = isFailedBackupEmailMuted
setIsFailedBackupEmailMuted(!isFailedBackupEmailMuted)
const updateResult = await updateSetting(
SettingName.create(SettingName.NAMES.MuteFailedBackupsEmails).getValue(),
`${!isFailedBackupEmailMuted}`,
)
if (!updateResult) {
setIsFailedBackupEmailMuted(previousValue)
}
}
const handleEmailFrequencyChange = (item: string) => {
updateEmailFrequency(item as EmailBackupFrequency).catch(console.error)
}
@@ -132,18 +108,6 @@ const EmailBackups = ({ application }: Props) => {
/>
)}
</div>
<HorizontalSeparator classes="my-4" />
<Subtitle>Email preferences</Subtitle>
<div className="flex justify-between gap-2 md:items-center">
<div className="flex flex-col">
<Text>Receive a notification email if an email backup fails.</Text>
</div>
{isLoading ? (
<Spinner className="h-5 w-5 flex-shrink-0" />
) : (
<Switch onChange={toggleMuteFailedBackupEmails} checked={!isFailedBackupEmailMuted} />
)}
</div>
</div>
</PreferencesSegment>
</PreferencesGroup>
@@ -1,9 +1,7 @@
import { NativeFeatureIdentifier, FeatureStatus } from '@standardnotes/snjs'
import { FunctionComponent, useEffect, useState } from 'react'
import { WebApplication } from '@/Application/WebApplication'
import { FunctionComponent } from 'react'
import TwoFactorAuthWrapper from './TwoFactorAuth/TwoFactorAuthWrapper'
import { MfaProps } from './TwoFactorAuth/MfaProps'
import Encryption from './Encryption'
import PasscodeLock from './PasscodeLock'
import Privacy from './Privacy'
@@ -12,14 +10,33 @@ import ErroredItems from './ErroredItems'
import PreferencesPane from '@/Components/Preferences/PreferencesComponents/PreferencesPane'
import BiometricsLock from '@/Components/Preferences/Panes/Security/BiometricsLock'
import MultitaskingPrivacy from '@/Components/Preferences/Panes/Security/MultitaskingPrivacy'
import U2FWrapper from './U2F/U2FWrapper'
import { TwoFactorAuth, is2FAEnabled as checkIf2FAIsEnabled } from './TwoFactorAuth/TwoFactorAuth'
import U2FView from './U2F/U2FView/U2FView'
import TwoFactorAuthView from './TwoFactorAuth/TwoFactorAuthView/TwoFactorAuthView'
interface SecurityProps extends MfaProps {
interface SecurityProps {
application: WebApplication
}
const Security: FunctionComponent<SecurityProps> = (props) => {
const isNativeMobileWeb = props.application.isNativeMobileWeb()
const [is2FAEnabled, setIs2FAEnabled] = useState(false)
const [canDisable2FA, setCanDisable2FA] = useState(true)
const [auth] = useState(
() =>
new TwoFactorAuth(props.application.sessions, props.application.mfa, (status) =>
setIs2FAEnabled(checkIf2FAIsEnabled(status)),
),
)
useEffect(() => {
auth.fetchStatus()
}, [auth])
const onU2FDevicesLoaded = (devices: Array<{ id: string; name: string }>) => {
setCanDisable2FA(devices.length === 0)
}
const isU2FFeatureAvailable =
props.application.features.getFeatureStatus(
@@ -31,8 +48,14 @@ const Security: FunctionComponent<SecurityProps> = (props) => {
<Encryption />
{props.application.items.invalidNonVaultedItems.length > 0 && <ErroredItems />}
<Protections application={props.application} />
<TwoFactorAuthWrapper application={props.application} />
{isU2FFeatureAvailable && <U2FWrapper application={props.application} />}
<TwoFactorAuthView auth={auth} application={props.application} canDisable2FA={canDisable2FA} />
{isU2FFeatureAvailable && (
<U2FView
application={props.application}
is2FAEnabled={is2FAEnabled}
loadAuthenticatorsCallback={onU2FDevicesLoaded}
/>
)}
{isNativeMobileWeb && <MultitaskingPrivacy application={props.application} />}
<PasscodeLock application={props.application} />
{isNativeMobileWeb && <BiometricsLock application={props.application} />}
@@ -1,5 +0,0 @@
import { WebApplication } from '@/Application/WebApplication'
export interface MfaProps {
application: WebApplication
}
@@ -19,6 +19,7 @@ export class TwoFactorAuth {
constructor(
private readonly sessions: SessionsClientInterface,
private readonly mfa: MfaServiceInterface,
private callback?: (status: TwoFactorStatus) => void,
) {
this._errorMessage = null
@@ -90,6 +91,9 @@ export class TwoFactorAuth {
action((active) => {
this._status = active ? 'two-factor-enabled' : 'two-factor-disabled'
this.setError(null)
if (this.callback) {
this.callback(this._status)
}
}),
)
.catch(
@@ -16,9 +16,10 @@ import ModalOverlay from '@/Components/Modal/ModalOverlay'
type Props = {
auth: TwoFactorAuth
application: WebApplication
canDisable2FA: boolean
}
const TwoFactorAuthView: FunctionComponent<Props> = ({ auth, application }) => {
const TwoFactorAuthView: FunctionComponent<Props> = ({ auth, application, canDisable2FA }) => {
const shouldShowActivationModal = auth.status !== 'fetching' && is2FAActivation(auth.status)
const activationModalTitle = shouldShowActivationModal
@@ -96,7 +97,7 @@ const TwoFactorAuthView: FunctionComponent<Props> = ({ auth, application }) => {
<TwoFactorTitle auth={auth} />
<TwoFactorDescription auth={auth} />
</div>
<TwoFactorSwitch auth={auth} />
<TwoFactorSwitch auth={auth} canDisable2FA={canDisable2FA} />
</div>
</PreferencesSegment>
@@ -6,9 +6,10 @@ import Spinner from '@/Components/Spinner/Spinner'
type Props = {
auth: TwoFactorAuth
canDisable2FA: boolean
}
const TwoFactorSwitch: FunctionComponent<Props> = ({ auth }) => {
const TwoFactorSwitch: FunctionComponent<Props> = ({ auth, canDisable2FA }) => {
if (!auth.isLoggedIn()) {
return null
}
@@ -17,7 +18,9 @@ const TwoFactorSwitch: FunctionComponent<Props> = ({ auth }) => {
return <Spinner className="h-4 w-4" />
}
return <Switch checked={!is2FADisabled(auth.status)} onChange={auth.toggle2FA} />
const shouldSwitchBeDisabled = auth.status === 'two-factor-enabled' && !canDisable2FA
return <Switch checked={!is2FADisabled(auth.status)} onChange={auth.toggle2FA} disabled={shouldSwitchBeDisabled} />
}
export default observer(TwoFactorSwitch)
@@ -1,12 +0,0 @@
import { FunctionComponent, useState } from 'react'
import { MfaProps } from './MfaProps'
import { TwoFactorAuth } from './TwoFactorAuth'
import TwoFactorAuthView from './TwoFactorAuthView/TwoFactorAuthView'
const TwoFactorAuthWrapper: FunctionComponent<MfaProps> = (props) => {
const [auth] = useState(() => new TwoFactorAuth(props.application.sessions, props.application.mfa))
auth.fetchStatus()
return <TwoFactorAuthView auth={auth} application={props.application} />
}
export default TwoFactorAuthWrapper
@@ -1,5 +0,0 @@
import { WebApplication } from '@/Application/WebApplication'
export interface U2FProps {
application: WebApplication
}
@@ -4,7 +4,11 @@ import { observer } from 'mobx-react-lite'
import { Text } from '@/Components/Preferences/PreferencesComponents/Content'
import { useApplication } from '@/Components/ApplicationProvider'
const U2FDescription: FunctionComponent = () => {
type Props = {
is2FAEnabled: boolean
}
const U2FDescription: FunctionComponent<Props> = ({ is2FAEnabled }) => {
const application = useApplication()
if (application.sessions.getUser() === undefined) {
@@ -17,6 +21,9 @@ const U2FDescription: FunctionComponent = () => {
{!application.isFullU2FClient && (
<Text className="italic">Please visit the web app in order to add a hardware security key.</Text>
)}
{!is2FAEnabled && (
<Text className="italic">You must enable two-factor authentication before adding a hardware security key.</Text>
)}
</div>
)
}
@@ -15,9 +15,11 @@ import RecoveryCodeBanner from '@/Components/RecoveryCodeBanner/RecoveryCodeBann
type Props = {
application: WebApplication
is2FAEnabled: boolean
loadAuthenticatorsCallback: (devices: Array<{ id: string; name: string }>) => void
}
const U2FView: FunctionComponent<Props> = ({ application }) => {
const U2FView: FunctionComponent<Props> = ({ application, is2FAEnabled, loadAuthenticatorsCallback }) => {
const [showDeviceAddingModal, setShowDeviceAddingModal] = useState(false)
const [devices, setDevices] = useState<Array<{ id: string; name: string }>>([])
const [error, setError] = useState('')
@@ -34,8 +36,10 @@ const U2FView: FunctionComponent<Props> = ({ application }) => {
return
}
setDevices(authenticatorListOrError.getValue())
}, [setError, setDevices, application])
const authenticatorList = authenticatorListOrError.getValue()
setDevices(authenticatorList)
loadAuthenticatorsCallback(authenticatorList)
}, [setError, setDevices, application, loadAuthenticatorsCallback])
useEffect(() => {
loadAuthenticatorDevices().catch(console.error)
@@ -47,7 +51,7 @@ const U2FView: FunctionComponent<Props> = ({ application }) => {
<PreferencesSegment>
<div className="flex flex-col">
<U2FTitle />
<U2FDescription />
<U2FDescription is2FAEnabled={is2FAEnabled} />
</div>
</PreferencesSegment>
<PreferencesSegment classes="mt-2">
@@ -60,7 +64,7 @@ const U2FView: FunctionComponent<Props> = ({ application }) => {
/>
<Button
className="mt-1"
disabled={!application.isFullU2FClient}
disabled={!application.isFullU2FClient || !is2FAEnabled}
label="Add Device"
primary
onClick={handleAddDeviceClick}
@@ -1,10 +0,0 @@
import { FunctionComponent } from 'react'
import { U2FProps } from './U2FProps'
import U2FView from './U2FView/U2FView'
const U2FWrapper: FunctionComponent<U2FProps> = (props) => {
return <U2FView application={props.application} />
}
export default U2FWrapper

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