Compare commits

...
Author SHA1 Message Date
StandardNotes CI ddc290e302 chore(release): publish
- @standardnotes/[email protected].8
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].9
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-03-10 20:13:08 +00:00
Karol Sójko 0ca26d0f75 chore: features fix specs 2023-03-10 20:40:23 +01:00
Karol Sójko bd4bc0614e chore: features fix to enable u2f for INTERNAL_TEAM_USER role 2023-03-10 20:19:43 +01:00
StandardNotes CI 2524d2615c chore(release): publish
- @standardnotes/[email protected].7
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].9
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].8
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-03-10 14:15:09 +00:00
Karol Sójko 7eab5dc680 chore: fix features to remove u2f from pro subscription 2023-03-10 14:46:34 +01:00
StandardNotes CI 09c503da68 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-03-09 12:27:50 +00:00
Karol Sójko 2fd879bb2d Revert "chore: add temporary error log on authenticator authentication options generation"
This reverts commit c098256f2f.
2023-03-09 13:01:14 +01:00
Karol Sójko 33e6ff67d6 chore: remove redundant testing procedure during web deployment - already tested on publish job 2023-03-09 12:47:34 +01:00
StandardNotes CI bac39f45c5 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-03-09 11:41:25 +00:00
Karol Sójko c098256f2f chore: add temporary error log on authenticator authentication options generation 2023-03-09 12:10:27 +01:00
StandardNotes CI 9c9f6ce0f3 chore(release): publish
- @standardnotes/[email protected].6
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].8
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].7
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-03-09 10:39:31 +00:00
Karol Sójko 54f1e618de chore: store authenticator devices labels in preferences instead of server (#2252) 2023-03-09 11:05:15 +01:00
StandardNotes CI aeab3fed0d chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].9
 - @standardnotes/[email protected]
2023-03-08 12:42:18 +00:00
Karol Sójko 5bd7e785c8 chore: change u2f from feature trunk to role based permission restricted (#2250) 2023-03-08 13:15:16 +01:00
Karol Sójko 896834f65a chore(web): put sign-in email notifications setting under paywall (#2249)
* chore: upgrade setting names to value objects

* chore(web): put sign-in email notifications setting under paywall

* chore: fix using setting name value objects in mocha tests

* chore: fix wording on email notifications titles
2023-03-08 12:53:59 +01:00
64 changed files with 523 additions and 152 deletions
-15
View File
@@ -12,22 +12,7 @@ on:
- '!*standardnotes/*web*alpha*'
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install dependencies
run: yarn install --immutable
- name: Build
run: yarn build:web
- name: ESLint
run: yarn lint
- name: Test
run: yarn test
deploy:
needs: test
runs-on: ubuntu-latest
steps:
+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.25.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/api
## [1.25.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/api
## [1.25.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/api
## [1.25.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/api
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api",
"version": "1.25.5",
"version": "1.25.8",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -1,6 +1,5 @@
export interface ListAuthenticatorsResponseBody {
authenticators: Array<{
id: string
name: string
}>
}
@@ -1,3 +1,3 @@
export interface VerifyAuthenticatorRegistrationResponseBody {
success: boolean
id: string
}
+24
View File
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.105.21](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/desktop
## [3.105.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/desktop
## [3.105.19](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/desktop
## [3.105.18](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/desktop
## [3.105.17](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/desktop
## [3.105.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/desktop
## [3.105.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**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.105.15",
"version": "3.105.21",
"license": "AGPL-3.0-or-later",
"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.22](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/encryption
## [1.21.21](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/encryption
## [1.21.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/encryption
## [1.21.19](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/encryption
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/encryption",
"version": "1.21.19",
"version": "1.21.22",
"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.58.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/features
## [1.58.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/features
## [1.58.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/features
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/features",
"version": "1.58.10",
"version": "1.58.12",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -2,11 +2,11 @@ import { SubscriptionName } from '@standardnotes/common'
import { GetFeatures, GetFeaturesForSubscription } from './Features'
describe('features', () => {
it('all features should have availableInSubscriptions populated', () => {
it('all features should have either availableInSubscriptions or availableInRoles populated', () => {
const features = GetFeatures()
for (const feature of features) {
expect(feature.availableInSubscriptions.length).toBeGreaterThan(0)
expect(feature.availableInSubscriptions.length > 0 || feature.availableInRoles !== undefined && feature.availableInRoles.length > 0).toBeTruthy()
}
})
it('gets features for plus plan', () => {
@@ -12,7 +12,8 @@ export function serverFeatures(): ServerFeatureDescription[] {
permission_name: PermissionName.TwoFactorAuth,
},
{
availableInSubscriptions: [SubscriptionName.ProPlan],
availableInSubscriptions: [],
availableInRoles: ['INTERNAL_TEAM_USER'],
name: 'U2F authentication',
identifier: FeatureIdentifier.UniversalSecondFactor,
permission_name: PermissionName.UniversalSecondFactor,
+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.27](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.28.26](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.28.25](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.28.24](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/filepicker
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/filepicker",
"version": "1.28.24",
"version": "1.28.27",
"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.14.37](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/files
## [1.14.36](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/files
## [1.14.35](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/files
## [1.14.34](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/files
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files",
"version": "1.14.34",
"version": "1.14.37",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+24
View File
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.51.52](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/mobile
## [3.51.51](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/mobile
## [3.51.50](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/mobile
## [3.51.49](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/mobile
## [3.51.48](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/mobile
## [3.51.47](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/mobile
## [3.51.46](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/mobile
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/mobile",
"version": "3.51.46",
"version": "3.51.52",
"author": "Standard Notes.",
"private": true,
"license": "AGPL-3.0-or-later",
+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.43.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/models
## [1.43.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/models
## [1.43.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/models
## [1.43.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/models
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/models",
"version": "1.43.7",
"version": "1.43.10",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -44,6 +44,7 @@ export enum PrefKey {
MomentsDefaultTagUuid = 'momentsDefaultTagUuid',
SystemViewPreferences = 'systemViewPreferences',
SuperNoteExportFormat = 'superNoteExportFormat',
AuthenticatorNames = 'authenticatorNames',
}
export enum NewNoteTitleFormat {
@@ -111,4 +112,5 @@ export type PrefValue = {
[PrefKey.MomentsDefaultTagUuid]: string | undefined
[PrefKey.SystemViewPreferences]: Partial<Record<SystemViewId, TagPreferences>>
[PrefKey.SuperNoteExportFormat]: 'json' | 'md' | 'html'
[PrefKey.AuthenticatorNames]: string
}
+24
View File
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.4.195](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.194](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.193](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.192](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.191](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.190](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/releases
## [1.4.189](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/releases
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/releases",
"version": "1.4.189",
"version": "1.4.195",
"license": "AGPL-3.0-or-later",
"main": "dist/releases.json",
"types": "dist/index.d.ts",
+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.13.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/responses
## [1.13.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/responses
## [1.13.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/responses
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/responses",
"version": "1.13.11",
"version": "1.13.13",
"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.57.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/services
## [1.57.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/services
## [1.57.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/services
## [1.57.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/services
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/services",
"version": "1.57.6",
"version": "1.57.9",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -3,14 +3,17 @@
import { AuthenticatorApiServiceInterface } from '@standardnotes/api'
import { Username, Uuid } from '@standardnotes/domain-core'
import { isErrorResponse } from '@standardnotes/responses'
import { PrefKey } from '@standardnotes/models'
import { InternalEventBusInterface } from '../Internal/InternalEventBusInterface'
import { AbstractService } from '../Service/AbstractService'
import { AuthenticatorClientInterface } from './AuthenticatorClientInterface'
import { PreferenceServiceInterface } from '../Preferences/PreferenceServiceInterface'
export class AuthenticatorManager extends AbstractService implements AuthenticatorClientInterface {
constructor(
private authenticatorApiService: AuthenticatorApiServiceInterface,
private preferencesService: PreferenceServiceInterface,
protected override internalEventBus: InternalEventBusInterface,
) {
super(internalEventBus)
@@ -24,7 +27,18 @@ export class AuthenticatorManager extends AbstractService implements Authenticat
return []
}
return result.data.authenticators
const authenticatorNames = this.getAuthenticatorNamesFromPreferences()
const nameDecoratedAuthenticators: { id: string; name: string }[] = result.data.authenticators.map(
(authenticator: { id: string }) => ({
id: authenticator.id,
name: authenticatorNames.has(authenticator.id)
? (authenticatorNames.get(authenticator.id) as string)
: 'Security Key',
}),
)
return nameDecoratedAuthenticators
} catch (error) {
return []
}
@@ -37,6 +51,11 @@ export class AuthenticatorManager extends AbstractService implements Authenticat
return false
}
const authenticatorNames = this.getAuthenticatorNamesFromPreferences()
authenticatorNames.delete(authenticatorId.value)
await this.preferencesService.setValue(PrefKey.AuthenticatorNames, JSON.stringify([...authenticatorNames]))
return true
} catch (error) {
return false
@@ -73,7 +92,12 @@ export class AuthenticatorManager extends AbstractService implements Authenticat
return false
}
return result.data.success
const authenticatorNames = this.getAuthenticatorNamesFromPreferences()
authenticatorNames.set(result.data.id, name)
await this.preferencesService.setValue(PrefKey.AuthenticatorNames, JSON.stringify([...authenticatorNames]))
return true
} catch (error) {
return false
}
@@ -92,4 +116,18 @@ export class AuthenticatorManager extends AbstractService implements Authenticat
return null
}
}
private getAuthenticatorNamesFromPreferences(): Map<string, string> {
let authenticatorNames: Map<string, string> = new Map()
const authenticatorNamesFromPreferences = this.preferencesService.getValue(PrefKey.AuthenticatorNames)
if (authenticatorNamesFromPreferences !== undefined) {
try {
authenticatorNames = new Map(JSON.parse(authenticatorNamesFromPreferences))
} catch (error) {
authenticatorNames = new Map()
}
}
return authenticatorNames
}
}
+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.
## [2.166.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/snjs
## [2.166.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/snjs
## [2.166.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
### Reverts
* Revert "chore: add temporary error log on authenticator authentication options generation" ([2fd879b](https://github.com/standardnotes/app/commit/2fd879bb2df57678c87f70b062c0592d1c6c654c))
## [2.166.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/snjs
## [2.166.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/snjs
## [2.166.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/snjs
## [2.166.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/snjs
+5 -1
View File
@@ -1775,7 +1775,11 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
const authenticatorApiService = new AuthenticatorApiService(authenticatorServer)
this.authenticatorManager = new AuthenticatorManager(authenticatorApiService, this.internalEventBus)
this.authenticatorManager = new AuthenticatorManager(
authenticatorApiService,
this.preferencesService,
this.internalEventBus,
)
}
private createAuthManager() {
@@ -8,7 +8,9 @@ export class GetRecoveryCodes implements UseCaseInterface<string> {
constructor(private authClient: AuthClientInterface, private settingsClient: SettingsClientInterface) {}
async execute(): Promise<Result<string>> {
const existingRecoveryCodes = await this.settingsClient.getSetting(SettingName.RecoveryCodes)
const existingRecoveryCodes = await this.settingsClient.getSetting(
SettingName.create(SettingName.NAMES.RecoveryCodes).getValue(),
)
if (existingRecoveryCodes !== undefined) {
return Result.ok(existingRecoveryCodes)
}
+5 -12
View File
@@ -1,6 +1,5 @@
import { FeatureDescription } from '@standardnotes/features'
import { joinPaths } from '@standardnotes/utils'
import { SettingName, SubscriptionSettingName } from '@standardnotes/settings'
import {
AbstractService,
ApiServiceInterface,
@@ -568,31 +567,25 @@ export class SNApiService
})
}
async getSetting(userUuid: UuidString, settingName: SettingName): Promise<HttpResponse<GetSettingResponse>> {
async getSetting(userUuid: UuidString, settingName: string): Promise<HttpResponse<GetSettingResponse>> {
return await this.tokenRefreshableRequest<GetSettingResponse>({
verb: HttpVerb.Get,
url: joinPaths(this.host, Paths.v1.setting(userUuid, settingName.toLowerCase() as SettingName)),
url: joinPaths(this.host, Paths.v1.setting(userUuid, settingName.toLowerCase())),
authentication: this.getSessionAccessToken(),
fallbackErrorMessage: API_MESSAGE_FAILED_GET_SETTINGS,
})
}
async getSubscriptionSetting(
userUuid: UuidString,
settingName: SubscriptionSettingName,
): Promise<HttpResponse<GetSettingResponse>> {
async getSubscriptionSetting(userUuid: UuidString, settingName: string): Promise<HttpResponse<GetSettingResponse>> {
return await this.tokenRefreshableRequest<GetSettingResponse>({
verb: HttpVerb.Get,
url: joinPaths(
this.host,
Paths.v1.subscriptionSetting(userUuid, settingName.toLowerCase() as SubscriptionSettingName),
),
url: joinPaths(this.host, Paths.v1.subscriptionSetting(userUuid, settingName.toLowerCase())),
authentication: this.getSessionAccessToken(),
fallbackErrorMessage: API_MESSAGE_FAILED_GET_SETTINGS,
})
}
async deleteSetting(userUuid: UuidString, settingName: SettingName): Promise<HttpResponse<DeleteSettingResponse>> {
async deleteSetting(userUuid: UuidString, settingName: string): Promise<HttpResponse<DeleteSettingResponse>> {
return this.tokenRefreshableRequest<DeleteSettingResponse>({
verb: HttpVerb.Delete,
url: joinPaths(this.host, Paths.v1.setting(userUuid, settingName)),
+2 -4
View File
@@ -1,5 +1,3 @@
import { SettingName, SubscriptionSettingName } from '@standardnotes/settings'
const FilesPaths = {
closeUploadSession: '/v1/files/upload/close-session',
createFileValetToken: '/v1/files/valet-tokens',
@@ -31,8 +29,8 @@ const ItemsPaths = {
const SettingsPaths = {
settings: (userUuid: string) => `/v1/users/${userUuid}/settings`,
setting: (userUuid: string, settingName: SettingName) => `/v1/users/${userUuid}/settings/${settingName}`,
subscriptionSetting: (userUuid: string, settingName: SubscriptionSettingName) =>
setting: (userUuid: string, settingName: string) => `/v1/users/${userUuid}/settings/${settingName}`,
subscriptionSetting: (userUuid: string, settingName: string) =>
`/v1/users/${userUuid}/subscription-settings/${settingName}`,
}
@@ -725,7 +725,7 @@ describe('featuresService', () => {
const featuresService = createService()
await featuresService.migrateFeatureRepoToUserSetting([extensionRepoItem])
expect(settingsService.updateSetting).toHaveBeenCalledWith(SettingName.ExtensionKey, extensionKey, true)
expect(settingsService.updateSetting).toHaveBeenCalledWith(SettingName.create(SettingName.NAMES.ExtensionKey).getValue(), extensionKey, true)
})
})
@@ -341,7 +341,11 @@ export class SNFeaturesService
const userKeyMatch = repoUrl.match(/\w{32,64}/)
if (userKeyMatch && userKeyMatch.length > 0) {
const userKey = userKeyMatch[0]
await this.settingsService.updateSetting(SettingName.ExtensionKey, userKey, true)
await this.settingsService.updateSetting(
SettingName.create(SettingName.NAMES.ExtensionKey).getValue(),
userKey,
true,
)
await this.itemManager.changeFeatureRepo(item, (m) => {
m.migratedToUserSetting = true
})
@@ -108,7 +108,9 @@ export class ListedService extends AbstractService implements ListedClientInterf
}
private async getSettingsBasedListedAccounts(): Promise<ListedAccount[]> {
const response = await this.settingsService.getSetting(SettingName.ListedAuthorSecrets)
const response = await this.settingsService.getSetting(
SettingName.create(SettingName.NAMES.ListedAuthorSecrets).getValue(),
)
if (!response) {
return []
}
+9 -3
View File
@@ -16,11 +16,17 @@ export class SNMfaService extends AbstractService {
}
private async saveMfaSetting(secret: string): Promise<void> {
return await this.settingsService.updateSetting(SettingName.MfaSecret, secret, true)
return await this.settingsService.updateSetting(
SettingName.create(SettingName.NAMES.MfaSecret).getValue(),
secret,
true,
)
}
async isMfaActivated(): Promise<boolean> {
const mfaSetting = await this.settingsService.getDoesSensitiveSettingExist(SettingName.MfaSecret)
const mfaSetting = await this.settingsService.getDoesSensitiveSettingExist(
SettingName.create(SettingName.NAMES.MfaSecret).getValue(),
)
return mfaSetting != false
}
@@ -43,7 +49,7 @@ export class SNMfaService extends AbstractService {
}
async disableMfa(): Promise<void> {
return await this.settingsService.deleteSetting(SettingName.MfaSecret)
return await this.settingsService.deleteSetting(SettingName.create(SettingName.NAMES.MfaSecret).getValue())
}
override deinit(): void {
@@ -1,13 +1,7 @@
import { SNApiService } from '../Api/ApiService'
import { SettingsGateway } from './SettingsGateway'
import { SNSessionManager } from '../Session/SessionManager'
import {
CloudProvider,
EmailBackupFrequency,
SettingName,
SensitiveSettingName,
SubscriptionSettingName,
} from '@standardnotes/settings'
import { CloudProvider, EmailBackupFrequency, SettingName } from '@standardnotes/settings'
import { ExtensionsServerURL } from '@Lib/Hosts'
import { AbstractService, InternalEventBusInterface } from '@standardnotes/services'
import { SettingsClientInterface } from './SettingsClientInterface'
@@ -46,7 +40,7 @@ export class SNSettingsService extends AbstractService implements SettingsClient
return this.provider.getSetting(name)
}
async getSubscriptionSetting(name: SubscriptionSettingName) {
async getSubscriptionSetting(name: SettingName) {
return this.provider.getSubscriptionSetting(name)
}
@@ -54,7 +48,7 @@ export class SNSettingsService extends AbstractService implements SettingsClient
return this.provider.updateSetting(name, payload, sensitive)
}
async getDoesSensitiveSettingExist(name: SensitiveSettingName) {
async getDoesSensitiveSettingExist(name: SettingName) {
return this.provider.getDoesSensitiveSettingExist(name)
}
@@ -1,4 +1,4 @@
import { SettingName, SensitiveSettingName, EmailBackupFrequency } from '@standardnotes/settings'
import { SettingName, EmailBackupFrequency } from '@standardnotes/settings'
import { SettingsList } from './SettingsList'
export interface SettingsClientInterface {
@@ -6,7 +6,7 @@ export interface SettingsClientInterface {
getSetting(name: SettingName): Promise<string | undefined>
getDoesSensitiveSettingExist(name: SensitiveSettingName): Promise<boolean>
getDoesSensitiveSettingExist(name: SettingName): Promise<boolean>
updateSetting(name: SettingName, payload: string, sensitive?: boolean): Promise<void>
@@ -1,5 +1,5 @@
import { SettingsList } from './SettingsList'
import { SettingName, SensitiveSettingName, SubscriptionSettingName } from '@standardnotes/settings'
import { SettingName } from '@standardnotes/settings'
import { API_MESSAGE_INVALID_SESSION } from '@standardnotes/services'
import { HttpStatusCode, isErrorResponse, User } from '@standardnotes/responses'
import { SettingsServerInterface } from './SettingsServerInterface'
@@ -46,7 +46,7 @@ export class SettingsGateway {
}
async getSetting(name: SettingName): Promise<string | undefined> {
const response = await this.settingsApi.getSetting(this.userUuid, name)
const response = await this.settingsApi.getSetting(this.userUuid, name.value)
if (response.status === HttpStatusCode.BadRequest) {
return undefined
@@ -59,8 +59,12 @@ export class SettingsGateway {
return response?.data?.setting?.value ?? undefined
}
async getSubscriptionSetting(name: SubscriptionSettingName): Promise<string | undefined> {
const response = await this.settingsApi.getSubscriptionSetting(this.userUuid, name)
async getSubscriptionSetting(name: SettingName): Promise<string | undefined> {
if (!name.isASubscriptionSetting()) {
throw new Error(`Setting ${name.value} is not a subscription setting`)
}
const response = await this.settingsApi.getSubscriptionSetting(this.userUuid, name.value)
if (response.status === HttpStatusCode.BadRequest) {
return undefined
@@ -73,8 +77,12 @@ export class SettingsGateway {
return response?.data?.setting?.value ?? undefined
}
async getDoesSensitiveSettingExist(name: SensitiveSettingName): Promise<boolean> {
const response = await this.settingsApi.getSetting(this.userUuid, name)
async getDoesSensitiveSettingExist(name: SettingName): Promise<boolean> {
if (!name.isSensitive()) {
throw new Error(`Setting ${name.value} is not sensitive`)
}
const response = await this.settingsApi.getSetting(this.userUuid, name.value)
if (response.status === HttpStatusCode.BadRequest) {
return false
@@ -88,14 +96,14 @@ export class SettingsGateway {
}
async updateSetting(name: SettingName, payload: string, sensitive: boolean): Promise<void> {
const response = await this.settingsApi.updateSetting(this.userUuid, name, payload, sensitive)
const response = await this.settingsApi.updateSetting(this.userUuid, name.value, payload, sensitive)
if (isErrorResponse(response)) {
throw new Error(response.data?.error.message)
}
}
async deleteSetting(name: SettingName): Promise<void> {
const response = await this.settingsApi.deleteSetting(this.userUuid, name)
const response = await this.settingsApi.deleteSetting(this.userUuid, name.value)
if (isErrorResponse(response)) {
throw new Error(response.data?.error.message)
}
@@ -28,16 +28,16 @@ type SettingType =
| OneDriveBackupFrequency
export class SettingsList {
private map: Partial<Record<SettingName, SettingData>> = {}
private map: Partial<Record<string, SettingData>> = {}
constructor(settings: SettingData[]) {
for (const setting of settings) {
this.map[setting.name as SettingName] = setting
this.map[setting.name] = setting
}
}
getSettingValue<T = SettingType, D = SettingType>(setting: SettingName, defaultValue: D): T {
const settingData = this.map[setting]
getSettingValue<T = SettingType, D = SettingType>(settingName: SettingName, defaultValue: D): T {
const settingData = this.map[settingName.value]
return (settingData?.value as unknown as T) || (defaultValue as unknown as T)
}
}
+1 -1
View File
@@ -194,7 +194,7 @@ describe('features', () => {
return false
})
expect(await application.settings.getDoesSensitiveSettingExist(SettingName.ExtensionKey)).to.equal(false)
expect(await application.settings.getDoesSensitiveSettingExist(SettingName.create(SettingName.NAMES.ExtensionKey).getValue())).to.equal(false)
const extensionKey = UuidGenerator.GenerateUuid().split('-').join('')
+2 -2
View File
@@ -26,13 +26,13 @@ describe('account recovery', function () {
})
it('should get the same recovery code at each consecutive call', async () => {
let recoveryCodesSetting = await application.settings.getSetting(SettingName.RecoveryCodes)
let recoveryCodesSetting = await application.settings.getSetting(SettingName.create(SettingName.NAMES.RecoveryCodes).getValue())
expect(recoveryCodesSetting).to.equal(undefined)
const generatedRecoveryCodesAfterFirstCall = await application.getRecoveryCodes.execute()
expect(generatedRecoveryCodesAfterFirstCall.getValue().length).to.equal(49)
recoveryCodesSetting = await application.settings.getSetting(SettingName.RecoveryCodes)
recoveryCodesSetting = await application.settings.getSetting(SettingName.create(SettingName.NAMES.RecoveryCodes).getValue())
expect(recoveryCodesSetting).to.equal(generatedRecoveryCodesAfterFirstCall.getValue())
const fetchedRecoveryCodesOnTheSecondCall = await application.getRecoveryCodes.execute()
+13 -13
View File
@@ -7,7 +7,7 @@ const expect = chai.expect
describe('settings service', function () {
this.timeout(Factory.ThirtySecondTimeout)
const validSetting = SettingName.GoogleDriveBackupFrequency
const validSetting = SettingName.create(SettingName.NAMES.GoogleDriveBackupFrequency).getValue()
const fakePayload = 'Im so meta even this acronym'
const updatedFakePayload = 'is meta'
@@ -98,22 +98,22 @@ describe('settings service', function () {
})
it('reads a nonexistent sensitive setting', async () => {
const setting = await application.settings.getDoesSensitiveSettingExist(SettingName.MfaSecret)
const setting = await application.settings.getDoesSensitiveSettingExist(SettingName.create(SettingName.NAMES.MfaSecret).getValue())
expect(setting).to.equal(false)
})
it('creates and reads a sensitive setting', async () => {
await application.settings.updateSetting(SettingName.MfaSecret, 'fake_secret', true)
const setting = await application.settings.getDoesSensitiveSettingExist(SettingName.MfaSecret)
await application.settings.updateSetting(SettingName.create(SettingName.NAMES.MfaSecret).getValue(), 'fake_secret', true)
const setting = await application.settings.getDoesSensitiveSettingExist(SettingName.create(SettingName.NAMES.MfaSecret).getValue())
expect(setting).to.equal(true)
})
it('creates and lists a sensitive setting', async () => {
await application.settings.updateSetting(SettingName.MfaSecret, 'fake_secret', true)
await application.settings.updateSetting(SettingName.MuteFailedBackupsEmails, MuteFailedBackupsEmailsOption.Muted)
await application.settings.updateSetting(SettingName.create(SettingName.NAMES.MfaSecret).getValue(), 'fake_secret', true)
await application.settings.updateSetting(SettingName.create(SettingName.NAMES.MuteFailedBackupsEmails).getValue(), MuteFailedBackupsEmailsOption.Muted)
const settings = await application.settings.listSettings()
expect(settings.getSettingValue(SettingName.MuteFailedBackupsEmails)).to.eql(MuteFailedBackupsEmailsOption.Muted)
expect(settings.getSettingValue(SettingName.MfaSecret)).to.not.be.ok
expect(settings.getSettingValue(SettingName.create(SettingName.NAMES.MuteFailedBackupsEmails).getValue())).to.eql(MuteFailedBackupsEmailsOption.Muted)
expect(settings.getSettingValue(SettingName.create(SettingName.NAMES.MfaSecret).getValue())).to.not.be.ok
})
it('reads a subscription setting', async () => {
@@ -135,7 +135,7 @@ describe('settings service', function () {
await Factory.sleep(2)
const setting = await application.settings.getSubscriptionSetting('FILE_UPLOAD_BYTES_LIMIT')
const setting = await application.settings.getSubscriptionSetting(SettingName.create(SettingName.NAMES.FileUploadBytesLimit).getValue())
expect(setting).to.be.a('string')
})
@@ -166,10 +166,10 @@ describe('settings service', function () {
await Factory.sleep(1)
const limitSettingBefore = await application.settings.getSubscriptionSetting('FILE_UPLOAD_BYTES_LIMIT')
const limitSettingBefore = await application.settings.getSubscriptionSetting(SettingName.create(SettingName.NAMES.FileUploadBytesLimit).getValue())
expect(limitSettingBefore).to.equal('107374182400')
const usedSettingBefore = await application.settings.getSubscriptionSetting('FILE_UPLOAD_BYTES_USED')
const usedSettingBefore = await application.settings.getSubscriptionSetting(SettingName.create(SettingName.NAMES.FileUploadBytesUsed).getValue())
expect(usedSettingBefore).to.equal('196')
await Factory.publishMockedEvent('SUBSCRIPTION_EXPIRED', {
@@ -202,10 +202,10 @@ describe('settings service', function () {
})
await Factory.sleep(1)
const limitSettingAfter = await application.settings.getSubscriptionSetting('FILE_UPLOAD_BYTES_LIMIT')
const limitSettingAfter = await application.settings.getSubscriptionSetting(SettingName.create(SettingName.NAMES.FileUploadBytesLimit).getValue())
expect(limitSettingAfter).to.equal(limitSettingBefore)
const usedSettingAfter = await application.settings.getSubscriptionSetting('FILE_UPLOAD_BYTES_USED')
const usedSettingAfter = await application.settings.getSubscriptionSetting(SettingName.create(SettingName.NAMES.FileUploadBytesUsed).getValue())
expect(usedSettingAfter).to.equal(usedSettingBefore)
})
})
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/snjs",
"version": "2.166.8",
"version": "2.166.14",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -46,7 +46,7 @@
"@standardnotes/responses": "workspace:*",
"@standardnotes/security": "^1.7.6",
"@standardnotes/services": "workspace:*",
"@standardnotes/settings": "^1.19.1",
"@standardnotes/settings": "^1.20.0",
"@standardnotes/sncrypto-common": "workspace:*",
"@standardnotes/sncrypto-web": "workspace:*",
"@standardnotes/utils": "workspace:*",
+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.24.37](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.24.36](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.24.35](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.24.34](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/ui-services
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/ui-services",
"version": "1.24.34",
"version": "1.24.37",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+24
View File
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.150.21](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/web
## [3.150.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)
**Note:** Version bump only for package @standardnotes/web
## [3.150.19](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/web
## [3.150.18](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/web
## [3.150.17](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)
**Note:** Version bump only for package @standardnotes/web
## [3.150.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/web
## [3.150.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)
**Note:** Version bump only for package @standardnotes/web
+66
View File
@@ -1,5 +1,71 @@
{
"versions": [
{
"version": "3.150.21",
"title": "[3.150.21](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.150.20",
"title": "[3.150.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-10)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.150.19",
"title": "[3.150.19](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.150.18",
"title": "[3.150.18](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.150.17",
"title": "[3.150.17](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-09)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.150.16",
"title": "[3.150.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"version": "3.150.15",
"title": "[3.150.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-03-08)",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/web",
"version": "3.150.15",
"version": "3.150.21",
"license": "AGPL-3.0-or-later",
"main": "dist/app.js",
"author": "Standard Notes.",
@@ -9,7 +9,7 @@ import SignOutWrapper from './SignOutView'
import FilesSection from './Files'
import PreferencesPane from '../../PreferencesComponents/PreferencesPane'
import SubscriptionSharing from './SubscriptionSharing/SubscriptionSharing'
import Email from './Email'
import Email from './Email/Email'
import DeleteAccount from '@/Components/Preferences/Panes/Account/DeleteAccount'
type Props = {
@@ -1,4 +1,10 @@
import { MuteMarketingEmailsOption, MuteSignInEmailsOption, SettingName } from '@standardnotes/snjs'
import {
FeatureIdentifier,
FeatureStatus,
MuteMarketingEmailsOption,
MuteSignInEmailsOption,
SettingName,
} from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite'
import { FunctionComponent, useCallback, useEffect, useState } from 'react'
@@ -10,6 +16,7 @@ import { STRING_FAILED_TO_UPDATE_USER_SETTING } from '@/Constants/Strings'
import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup'
import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment'
import Spinner from '@/Components/Spinner/Spinner'
import NoProSubscription from '../NoProSubscription'
type Props = {
application: WebApplication
@@ -20,6 +27,9 @@ const Email: FunctionComponent<Props> = ({ application }: Props) => {
const [marketingEmailsMutedValue, setMarketingEmailsMutedValue] = useState(MuteMarketingEmailsOption.NotMuted)
const [isLoading, setIsLoading] = useState(true)
const isMuteSignInEmailsFeatureAvailable =
application.features.getFeatureStatus(FeatureIdentifier.SignInAlerts) === FeatureStatus.Entitled
const updateSetting = async (settingName: SettingName, payload: string): Promise<boolean> => {
try {
await application.settings.updateSetting(settingName, payload, false)
@@ -40,13 +50,13 @@ const Email: FunctionComponent<Props> = ({ application }: Props) => {
const userSettings = await application.settings.listSettings()
setSignInEmailsMutedValue(
userSettings.getSettingValue<MuteSignInEmailsOption>(
SettingName.MuteSignInEmails,
SettingName.create(SettingName.NAMES.MuteSignInEmails).getValue(),
MuteSignInEmailsOption.NotMuted,
),
),
setMarketingEmailsMutedValue(
userSettings.getSettingValue<MuteMarketingEmailsOption>(
SettingName.MuteMarketingEmails,
SettingName.create(SettingName.NAMES.MuteMarketingEmails).getValue(),
MuteMarketingEmailsOption.NotMuted,
),
)
@@ -67,7 +77,10 @@ const Email: FunctionComponent<Props> = ({ application }: Props) => {
previousValue === MuteSignInEmailsOption.Muted ? MuteSignInEmailsOption.NotMuted : MuteSignInEmailsOption.Muted
setSignInEmailsMutedValue(newValue)
const updateResult = await updateSetting(SettingName.MuteSignInEmails, newValue)
const updateResult = await updateSetting(
SettingName.create(SettingName.NAMES.MuteSignInEmails).getValue(),
newValue,
)
if (!updateResult) {
setSignInEmailsMutedValue(previousValue)
@@ -82,7 +95,10 @@ const Email: FunctionComponent<Props> = ({ application }: Props) => {
: MuteMarketingEmailsOption.Muted
setMarketingEmailsMutedValue(newValue)
const updateResult = await updateSetting(SettingName.MuteMarketingEmails, newValue)
const updateResult = await updateSetting(
SettingName.create(SettingName.NAMES.MuteMarketingEmails).getValue(),
newValue,
)
if (!updateResult) {
setMarketingEmailsMutedValue(previousValue)
@@ -96,25 +112,40 @@ const Email: FunctionComponent<Props> = ({ application }: Props) => {
<div>
<div className="flex items-center justify-between">
<div className="flex flex-col">
<Subtitle>Disable sign-in notification emails</Subtitle>
<Text>
Disables email notifications when a new sign-in occurs on your account. (Email notifications are
available only to paid subscribers).
</Text>
<Subtitle>Sign-in notification emails</Subtitle>
{isMuteSignInEmailsFeatureAvailable ? (
<Text>
Disables email notifications when a new sign-in occurs on your account. (Email notifications are
available only to paid subscribers).
</Text>
) : (
<NoProSubscription
application={application}
text={
<span>
Sign-in notification emails are available only on a{' '}
<span className="font-bold">subscription</span> plan. Please upgrade in order to enable sign-in
notifications.
</span>
}
/>
)}
</div>
{isLoading ? (
<Spinner className="ml-2 flex-shrink-0" />
) : (
<Switch
onChange={toggleMuteSignInEmails}
checked={signInEmailsMutedValue === MuteSignInEmailsOption.Muted}
/>
isMuteSignInEmailsFeatureAvailable && (
<Switch
onChange={toggleMuteSignInEmails}
checked={signInEmailsMutedValue === MuteSignInEmailsOption.Muted}
/>
)
)}
</div>
<HorizontalSeparator classes="my-4" />
<div className="flex items-center justify-between">
<div className="flex flex-col">
<Subtitle>Disable marketing notification emails</Subtitle>
<Subtitle>Marketing notification emails</Subtitle>
<Text>Disables email notifications with special deals and promotions.</Text>
</div>
{isLoading ? (
@@ -1,7 +1,7 @@
import { WebApplication } from '@/Application/Application'
import Spinner from '@/Components/Spinner/Spinner'
import { formatSizeToReadableString } from '@standardnotes/filepicker'
import { SubscriptionSettingName } from '@standardnotes/snjs'
import { SettingName } from '@standardnotes/snjs'
import { FunctionComponent, useEffect, useState } from 'react'
import { Subtitle, Title } from '../../PreferencesComponents/Content'
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
@@ -19,10 +19,10 @@ const FilesSection: FunctionComponent<Props> = ({ application }) => {
useEffect(() => {
const getFilesQuota = async () => {
const filesQuotaUsed = await application.settings.getSubscriptionSetting(
SubscriptionSettingName.FileUploadBytesUsed,
SettingName.create(SettingName.NAMES.FileUploadBytesUsed).getValue(),
)
const filesQuotaTotal = await application.settings.getSubscriptionSetting(
SubscriptionSettingName.FileUploadBytesLimit,
SettingName.create(SettingName.NAMES.FileUploadBytesLimit).getValue(),
)
if (filesQuotaUsed) {
@@ -1,13 +1,14 @@
import { FunctionComponent, useState } from 'react'
import { FunctionComponent, ReactNode, useState } from 'react'
import { LinkButton, Text } from '@/Components/Preferences/PreferencesComponents/Content'
import Button from '@/Components/Button/Button'
import { WebApplication } from '@/Application/Application'
type Props = {
application: WebApplication
text: ReactNode
}
const NoProSubscription: FunctionComponent<Props> = ({ application }) => {
const NoProSubscription: FunctionComponent<Props> = ({ application, text }) => {
const [isLoadingPurchaseFlow, setIsLoadingPurchaseFlow] = useState(false)
const [purchaseFlowError, setPurchaseFlowError] = useState<string | undefined>(undefined)
@@ -29,10 +30,7 @@ const NoProSubscription: FunctionComponent<Props> = ({ application }) => {
return (
<>
<Text>
Subscription sharing is available only on the <span className="font-bold">Professional</span> plan. Please
upgrade in order to share your subscription.
</Text>
<Text>{text}</Text>
{isLoadingPurchaseFlow && <Text>Redirecting you to the subscription page...</Text>}
{purchaseFlowError && <Text className="text-danger">{purchaseFlowError}</Text>}
@@ -9,7 +9,7 @@ import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/Pre
import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment'
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import NoProSubscription from './NoProSubscription'
import NoProSubscription from '../NoProSubscription'
import InvitationsList from './InvitationsList'
import Invite from './Invite/Invite'
import Button from '@/Components/Button/Button'
@@ -57,7 +57,15 @@ const SubscriptionSharing: FunctionComponent<Props> = ({ application, viewContro
</ModalOverlay>
</div>
) : (
<NoProSubscription application={application} />
<NoProSubscription
application={application}
text={
<span>
Subscription sharing is available only on the <span className="font-bold">Professional</span> plan.
Please upgrade in order to share your subscription.
</span>
}
/>
)}
</div>
</div>
@@ -82,18 +82,18 @@ const CloudBackupProvider: FunctionComponent<Props> = ({ application, providerNa
const backupSettingsData = {
[CloudProvider.Dropbox]: {
backupTokenSettingName: SettingName.DropboxBackupToken,
backupFrequencySettingName: SettingName.DropboxBackupFrequency,
backupTokenSettingName: SettingName.create(SettingName.NAMES.DropboxBackupToken).getValue(),
backupFrequencySettingName: SettingName.create(SettingName.NAMES.DropboxBackupFrequency).getValue(),
defaultBackupFrequency: DropboxBackupFrequency.Daily,
},
[CloudProvider.Google]: {
backupTokenSettingName: SettingName.GoogleDriveBackupToken,
backupFrequencySettingName: SettingName.GoogleDriveBackupFrequency,
backupTokenSettingName: SettingName.create(SettingName.NAMES.GoogleDriveBackupToken).getValue(),
backupFrequencySettingName: SettingName.create(SettingName.NAMES.GoogleDriveBackupFrequency).getValue(),
defaultBackupFrequency: GoogleDriveBackupFrequency.Daily,
},
[CloudProvider.OneDrive]: {
backupTokenSettingName: SettingName.OneDriveBackupToken,
backupFrequencySettingName: SettingName.OneDriveBackupFrequency,
backupTokenSettingName: SettingName.create(SettingName.NAMES.OneDriveBackupToken).getValue(),
backupFrequencySettingName: SettingName.create(SettingName.NAMES.OneDriveBackupFrequency).getValue(),
defaultBackupFrequency: OneDriveBackupFrequency.Daily,
},
}
@@ -41,7 +41,7 @@ const CloudLink: FunctionComponent<Props> = ({ application }) => {
setIsFailedCloudBackupEmailMuted(
convertStringifiedBooleanToBoolean(
userSettings.getSettingValue(
SettingName.MuteFailedCloudBackupsEmails,
SettingName.create(SettingName.NAMES.MuteFailedCloudBackupsEmails).getValue(),
MuteFailedCloudBackupsEmailsOption.NotMuted,
),
),
@@ -83,7 +83,7 @@ const CloudLink: FunctionComponent<Props> = ({ application }) => {
setIsFailedCloudBackupEmailMuted(!isFailedCloudBackupEmailMuted)
const updateResult = await updateSetting(
SettingName.MuteFailedCloudBackupsEmails,
SettingName.create(SettingName.NAMES.MuteFailedCloudBackupsEmails).getValue(),
`${!isFailedCloudBackupEmailMuted}`,
)
if (!updateResult) {
@@ -34,14 +34,14 @@ const EmailBackups = ({ application }: Props) => {
const userSettings = await application.settings.listSettings()
setEmailFrequency(
userSettings.getSettingValue<EmailBackupFrequency>(
SettingName.EmailBackupFrequency,
SettingName.create(SettingName.NAMES.EmailBackupFrequency).getValue(),
EmailBackupFrequency.Disabled,
),
)
setIsFailedBackupEmailMuted(
convertStringifiedBooleanToBoolean(
userSettings.getSettingValue<MuteFailedBackupsEmailsOption>(
SettingName.MuteFailedBackupsEmails,
SettingName.create(SettingName.NAMES.MuteFailedBackupsEmails).getValue(),
MuteFailedBackupsEmailsOption.NotMuted,
),
),
@@ -81,7 +81,10 @@ const EmailBackups = ({ application }: Props) => {
const previousFrequency = emailFrequency
setEmailFrequency(frequency)
const updateResult = await updateSetting(SettingName.EmailBackupFrequency, frequency)
const updateResult = await updateSetting(
SettingName.create(SettingName.NAMES.EmailBackupFrequency).getValue(),
frequency,
)
if (!updateResult) {
setEmailFrequency(previousFrequency)
}
@@ -91,7 +94,10 @@ const EmailBackups = ({ application }: Props) => {
const previousValue = isFailedBackupEmailMuted
setIsFailedBackupEmailMuted(!isFailedBackupEmailMuted)
const updateResult = await updateSetting(SettingName.MuteFailedBackupsEmails, `${!isFailedBackupEmailMuted}`)
const updateResult = await updateSetting(
SettingName.create(SettingName.NAMES.MuteFailedBackupsEmails).getValue(),
`${!isFailedBackupEmailMuted}`,
)
if (!updateResult) {
setIsFailedBackupEmailMuted(previousValue)
}
@@ -39,7 +39,7 @@ const Privacy: FunctionComponent<Props> = ({ application }: Props) => {
const userSettings = await application.settings.listSettings()
setSessionUaLoggingValue(
userSettings.getSettingValue<LogSessionUserAgentOption>(
SettingName.LogSessionUserAgent,
SettingName.create(SettingName.NAMES.LogSessionUserAgent).getValue(),
LogSessionUserAgentOption.Enabled,
),
)
@@ -62,7 +62,10 @@ const Privacy: FunctionComponent<Props> = ({ application }: Props) => {
: LogSessionUserAgentOption.Enabled
setSessionUaLoggingValue(newValue)
const updateResult = await updateSetting(SettingName.LogSessionUserAgent, newValue)
const updateResult = await updateSetting(
SettingName.create(SettingName.NAMES.LogSessionUserAgent).getValue(),
newValue,
)
if (!updateResult) {
setSessionUaLoggingValue(previousValue)
@@ -1,3 +1,5 @@
import { FeatureIdentifier, FeatureStatus } from '@standardnotes/snjs'
import { WebApplication } from '@/Application/Application'
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
import { FunctionComponent } from 'react'
@@ -12,7 +14,6 @@ import PreferencesPane from '@/Components/Preferences/PreferencesComponents/Pref
import BiometricsLock from '@/Components/Preferences/Panes/Security/BiometricsLock'
import MultitaskingPrivacy from '@/Components/Preferences/Panes/Security/MultitaskingPrivacy'
import U2FWrapper from './U2F/U2FWrapper'
import { featureTrunkEnabled, FeatureTrunkName } from '@/FeatureTrunk'
interface SecurityProps extends MfaProps {
viewControllerManager: ViewControllerManager
@@ -22,6 +23,9 @@ interface SecurityProps extends MfaProps {
const Security: FunctionComponent<SecurityProps> = (props) => {
const isNativeMobileWeb = props.application.isNativeMobileWeb()
const isU2FFeatureAvailable =
props.application.features.getFeatureStatus(FeatureIdentifier.UniversalSecondFactor) === FeatureStatus.Entitled
return (
<PreferencesPane>
<Encryption viewControllerManager={props.viewControllerManager} />
@@ -34,9 +38,7 @@ const Security: FunctionComponent<SecurityProps> = (props) => {
userProvider={props.userProvider}
application={props.application}
/>
{featureTrunkEnabled(FeatureTrunkName.U2F) && (
<U2FWrapper userProvider={props.userProvider} application={props.application} />
)}
{isU2FFeatureAvailable && <U2FWrapper userProvider={props.userProvider} application={props.application} />}
{isNativeMobileWeb && <MultitaskingPrivacy application={props.application} />}
<PasscodeLock viewControllerManager={props.viewControllerManager} application={props.application} />
{isNativeMobileWeb && <BiometricsLock application={props.application} />}
@@ -3,13 +3,11 @@ import { isDev } from '@/Utils'
export enum FeatureTrunkName {
Super,
ImportTools,
U2F,
}
const FeatureTrunkStatus: Record<FeatureTrunkName, boolean> = {
[FeatureTrunkName.Super]: isDev && true,
[FeatureTrunkName.ImportTools]: isDev && true,
[FeatureTrunkName.U2F]: isDev && true,
}
export function featureTrunkEnabled(trunk: FeatureTrunkName): boolean {
+6 -5
View File
@@ -5317,12 +5317,13 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/settings@npm:^1.19.1":
version: 1.19.1
resolution: "@standardnotes/settings@npm:1.19.1"
"@standardnotes/settings@npm:^1.20.0":
version: 1.20.0
resolution: "@standardnotes/settings@npm:1.20.0"
dependencies:
"@standardnotes/domain-core": ^1.11.3
reflect-metadata: ^0.1.13
checksum: d99d49d4401ac8c973284d8637195c0441e6f73b7e01e9eb4ab14feb27c6d2e928a493d944ed67ea1d6f229bf5ea839b5dd667c373b917aed321bb32972daacb
checksum: 6e8c03107eec03e3d800bb9ced690dbade6713f7ef5e19364aaf06a86a92d2d58ac629d2e948775223ae9798be3ec60edfc5c24a8f7a4d57de959e5937727f44
languageName: node
linkType: hard
@@ -5403,7 +5404,7 @@ __metadata:
"@standardnotes/responses": "workspace:*"
"@standardnotes/security": ^1.7.6
"@standardnotes/services": "workspace:*"
"@standardnotes/settings": ^1.19.1
"@standardnotes/settings": ^1.20.0
"@standardnotes/sncrypto-common": "workspace:*"
"@standardnotes/sncrypto-web": "workspace:*"
"@standardnotes/utils": "workspace:*"