Compare commits

...
Author SHA1 Message Date
StandardNotes CI 63c10c703f chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
2022-11-03 14:04:27 +00:00
Aman Harwara 4036113206 fix: files list not updating when new file is uploaded 2022-11-03 19:02:30 +05:30
Aman Harwara de4adca059 fix: "No modifications allowed" error on file drag in Firefox 2022-11-03 19:00:34 +05:30
Aman Harwara 9ae0ce0bfd fix(desktop): editor column top padding on mac 2022-11-03 18:34:59 +05:30
StandardNotes CI 455cdc01fc chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
2022-11-03 12:20:16 +00:00
Mo c4dbc5cbd2 fix: purchase flow close on complete 2022-11-03 06:46:07 -05:00
Mo 305ffdf984 fix: correctly refresh cta banner 2022-11-03 06:35:06 -05:00
Aman Harwara dc4530b2f3 fix(mobile): disable pinch zoom on mobile app UI 2022-11-03 16:49:32 +05:30
Aman Harwara d6cafa1e73 fix(desktop): selected column top padding on small windows 2022-11-03 16:28:28 +05:30
Aman Harwara ac96e197e0 fix(desktop): only add extra popover padding for small windows 2022-11-03 15:59:48 +05:30
StandardNotes CI 636963b409 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
2022-11-03 09:11:06 +00:00
Karol Sójko 7ead0f655b feat: add sending user requests from UI (#1927)
* feat: add sending user requests from UI

* fix(web): view controller manager user client references
2022-11-03 09:39:38 +01:00
StandardNotes CI 6b50372db2 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
2022-11-02 19:15:23 +00:00
Aman Harwara a6ef658dae feat: prioritize loading latest selected items (#1930) 2022-11-03 00:11:17 +05:30
StandardNotes CI 8c49ca5572 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
2022-11-02 17:36:31 +00:00
Mo 35b21b21ce fix: hide subscription marketing on iOS (#1929) 2022-11-02 12:07:26 -05:00
StandardNotes CI f3e2d80b44 chore(release): publish
- @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].0
2022-11-02 16:33:43 +00:00
Mo dd821c95e6 feat: dedicated files layout (#1928) 2022-11-02 11:06:19 -05:00
StandardNotes CI 1498cce37f chore(release): publish
- @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
2022-11-02 11:07:55 +00:00
Karol Sójko b2faa815e9 feat: add sending user requests to process (#1908)
* feat: add sending user requests to process

* fix(snjs): yarn lock

* fix(snjs): imports

* fix: specs
2022-11-02 11:33:02 +01:00
StandardNotes CI f687334d7d chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2022-11-01 21:26:41 +00:00
Mo 25ecdceea9 refactor: remove reliance on viewport height in favor of body (#1926) 2022-11-01 15:58:12 -05:00
Mo d3f04451af Revert "fix(mobile): viewport size on keyboard focus (#1925)"
This reverts commit e0b75946f6.
2022-11-01 14:06:06 -05:00
Mo e0b75946f6 fix(mobile): viewport size on keyboard focus (#1925) 2022-11-01 14:00:07 -05:00
StandardNotes CI ab0069cd68 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].8
 - @standardnotes/[email protected].9
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2022-11-01 17:11:32 +00:00
StandardNotes CI 5920a347bb chore(release): components 2022-11-01 17:11:18 +00:00
Mo 994f824757 fix(mobile): increase font sizes and other mobile-centric improvements (#1907) 2022-11-01 11:41:40 -05:00
StandardNotes CI f54b017f53 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
2022-10-31 17:26:56 +00:00
Mo 50b0db3baa fix(mobile): bump minimum android sdk to 28 (9.0) 2022-10-31 11:57:45 -05:00
StandardNotes CI 0ab79ec2da chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].7
 - @standardnotes/[email protected].8
2022-10-31 16:29:05 +00:00
Mo 8b25c01551 fix(mobile): decrease iOS deployment target to 13 2022-10-31 10:59:48 -05:00
Mo fef1bdf799 fix(web): support for older browsers like Safari 11 on iOS 13.7 2022-10-31 10:58:55 -05:00
Mo 50182fad4f fix(mobile): increase iOS deployment target to 14 2022-10-31 10:35:40 -05:00
StandardNotes CI 9f00944965 chore(release): publish
- @standardnotes/[email protected].9
 - @standardnotes/[email protected]
2022-10-31 14:18:15 +00:00
Mo 298ea73137 chore: fix android build 2022-10-31 08:50:49 -05:00
257 changed files with 2944 additions and 1087 deletions
+10
View File
@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.19.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/api
# [1.19.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
### Features
* add sending user requests to process ([#1908](https://github.com/standardnotes/app/issues/1908)) ([b2faa81](https://github.com/standardnotes/app/commit/b2faa815e967a9e7052b3ce6955e967c6bc68864))
## [1.18.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-27)
**Note:** Version bump only for package @standardnotes/api
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api",
"version": "1.18.3",
"version": "1.19.1",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -36,7 +36,7 @@
"typescript": "*"
},
"dependencies": {
"@standardnotes/common": "^1.39.0",
"@standardnotes/common": "^1.43.0",
"@standardnotes/encryption": "workspace:*",
"@standardnotes/models": "workspace:*",
"@standardnotes/responses": "workspace:*",
@@ -0,0 +1,5 @@
export enum UserApiOperations {
Registering,
SubmittingRequest,
DeletingAccount,
}
@@ -1,20 +1,35 @@
import { ProtocolVersion } from '@standardnotes/common'
import { ProtocolVersion, UserRequestType } from '@standardnotes/common'
import { RootKeyParamsInterface } from '@standardnotes/models'
import { UserDeletionResponse } from '../../Response/User/UserDeletionResponse'
import { UserRegistrationResponse } from '../../Response/User/UserRegistrationResponse'
import { UserRequestResponse } from '../../Response/UserRequest/UserRequestResponse'
import { UserServerInterface } from '../../Server'
import { UserRequestServerInterface } from '../../Server/UserRequest/UserRequestServerInterface'
import { UserApiOperations } from './UserApiOperations'
import { UserApiService } from './UserApiService'
describe('UserApiService', () => {
let userServer: UserServerInterface
let userRequestServer: UserRequestServerInterface
let keyParams: RootKeyParamsInterface
const createService = () => new UserApiService(userServer)
const createService = () => new UserApiService(userServer, userRequestServer)
beforeEach(() => {
userServer = {} as jest.Mocked<UserServerInterface>
userServer.register = jest.fn().mockReturnValue({
data: { user: { email: '[email protected]', uuid: '1-2-3' } },
} as jest.Mocked<UserRegistrationResponse>)
userServer.deleteAccount = jest.fn().mockReturnValue({
data: { message: 'Success' },
} as jest.Mocked<UserDeletionResponse>)
userRequestServer = {} as jest.Mocked<UserRequestServerInterface>
userRequestServer.submitUserRequest = jest.fn().mockReturnValue({
data: { success: true },
} as jest.Mocked<UserRequestResponse>)
keyParams = {} as jest.Mocked<RootKeyParamsInterface>
keyParams.getPortableValue = jest.fn().mockReturnValue({
@@ -51,8 +66,8 @@ describe('UserApiService', () => {
it('should not register a user if it is already registering', async () => {
const service = createService()
Object.defineProperty(service, 'registering', {
get: () => true,
Object.defineProperty(service, 'operationsInProgress', {
get: () => new Map([[UserApiOperations.Registering, true]]),
})
let error = null
@@ -84,4 +99,99 @@ describe('UserApiService', () => {
expect(error).not.toBeNull()
})
it('should submit a user request', async () => {
const response = await createService().submitUserRequest({
userUuid: '1-2-3',
requestType: UserRequestType.ExitDiscount,
})
expect(response).toEqual({
data: {
success: true,
},
})
expect(userRequestServer.submitUserRequest).toHaveBeenCalledWith({
userUuid: '1-2-3',
requestType: UserRequestType.ExitDiscount,
})
})
it('should not submit a user request if it is already submitting', async () => {
const service = createService()
Object.defineProperty(service, 'operationsInProgress', {
get: () => new Map([[UserApiOperations.SubmittingRequest, true]]),
})
let error = null
try {
await service.submitUserRequest({ userUuid: '1-2-3', requestType: UserRequestType.ExitDiscount })
} catch (caughtError) {
error = caughtError
}
expect(error).not.toBeNull()
})
it('should not submit a user request if the server fails', async () => {
userRequestServer.submitUserRequest = jest.fn().mockImplementation(() => {
throw new Error('Oops')
})
let error = null
try {
await createService().submitUserRequest({
userUuid: '1-2-3',
requestType: UserRequestType.ExitDiscount,
})
} catch (caughtError) {
error = caughtError
}
expect(error).not.toBeNull()
})
it('should delete a user', async () => {
const response = await createService().deleteAccount('1-2-3')
expect(response).toEqual({
data: {
message: 'Success',
},
})
expect(userServer.deleteAccount).toHaveBeenCalledWith({
userUuid: '1-2-3',
})
})
it('should not delete a user if it is already deleting', async () => {
const service = createService()
Object.defineProperty(service, 'operationsInProgress', {
get: () => new Map([[UserApiOperations.DeletingAccount, true]]),
})
let error = null
try {
await service.deleteAccount('1-2-3')
} catch (caughtError) {
error = caughtError
}
expect(error).not.toBeNull()
})
it('should not delete a user if the server fails', async () => {
userServer.deleteAccount = jest.fn().mockImplementation(() => {
throw new Error('Oops')
})
let error = null
try {
await createService().deleteAccount('1-2-3')
} catch (caughtError) {
error = caughtError
}
expect(error).not.toBeNull()
})
})
@@ -1,17 +1,57 @@
import { RootKeyParamsInterface } from '@standardnotes/models'
import { UserRequestType } from '@standardnotes/common'
import { ErrorMessage } from '../../Error/ErrorMessage'
import { ApiCallError } from '../../Error/ApiCallError'
import { UserRegistrationResponse } from '../../Response/User/UserRegistrationResponse'
import { UserServerInterface } from '../../Server/User/UserServerInterface'
import { ApiVersion } from '../../Api/ApiVersion'
import { ApiEndpointParam } from '../../Request/ApiEndpointParam'
import { UserRequestResponse } from '../../Response/UserRequest/UserRequestResponse'
import { UserDeletionResponse } from '../../Response/User/UserDeletionResponse'
import { UserRequestServerInterface } from '../../Server/UserRequest/UserRequestServerInterface'
import { UserApiOperations } from './UserApiOperations'
import { UserApiServiceInterface } from './UserApiServiceInterface'
export class UserApiService implements UserApiServiceInterface {
private registering: boolean
private operationsInProgress: Map<UserApiOperations, boolean>
constructor(private userServer: UserServerInterface) {
this.registering = false
constructor(private userServer: UserServerInterface, private userRequestServer: UserRequestServerInterface) {
this.operationsInProgress = new Map()
}
async deleteAccount(userUuid: string): Promise<UserDeletionResponse> {
this.lockOperation(UserApiOperations.DeletingAccount)
try {
const response = await this.userServer.deleteAccount({
userUuid: userUuid,
})
this.unlockOperation(UserApiOperations.DeletingAccount)
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericRegistrationFail)
}
}
async submitUserRequest(dto: { userUuid: string; requestType: UserRequestType }): Promise<UserRequestResponse> {
this.lockOperation(UserApiOperations.SubmittingRequest)
try {
const response = await this.userRequestServer.submitUserRequest({
userUuid: dto.userUuid,
requestType: dto.requestType,
})
this.unlockOperation(UserApiOperations.SubmittingRequest)
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericRegistrationFail)
}
}
async register(registerDTO: {
@@ -20,10 +60,7 @@ export class UserApiService implements UserApiServiceInterface {
keyParams: RootKeyParamsInterface
ephemeral: boolean
}): Promise<UserRegistrationResponse> {
if (this.registering) {
throw new ApiCallError(ErrorMessage.RegistrationInProgress)
}
this.registering = true
this.lockOperation(UserApiOperations.Registering)
try {
const response = await this.userServer.register({
@@ -34,11 +71,23 @@ export class UserApiService implements UserApiServiceInterface {
...registerDTO.keyParams.getPortableValue(),
})
this.registering = false
this.unlockOperation(UserApiOperations.Registering)
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericRegistrationFail)
}
}
private lockOperation(operation: UserApiOperations): void {
if (this.operationsInProgress.get(operation)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}
this.operationsInProgress.set(operation, true)
}
private unlockOperation(operation: UserApiOperations): void {
this.operationsInProgress.set(operation, false)
}
}
@@ -1,5 +1,9 @@
import { UserRequestType, Uuid } from '@standardnotes/common'
import { RootKeyParamsInterface } from '@standardnotes/models'
import { UserDeletionResponse } from '../../Response/User/UserDeletionResponse'
import { UserRegistrationResponse } from '../../Response/User/UserRegistrationResponse'
import { UserRequestResponse } from '../../Response/UserRequest/UserRequestResponse'
export interface UserApiServiceInterface {
register(registerDTO: {
@@ -8,4 +12,6 @@ export interface UserApiServiceInterface {
keyParams: RootKeyParamsInterface
ephemeral: boolean
}): Promise<UserRegistrationResponse>
submitUserRequest(dto: { userUuid: Uuid; requestType: UserRequestType }): Promise<UserRequestResponse>
deleteAccount(userUuid: string): Promise<UserDeletionResponse>
}
+1
View File
@@ -1,6 +1,7 @@
export * from './Subscription/SubscriptionApiOperations'
export * from './Subscription/SubscriptionApiService'
export * from './Subscription/SubscriptionApiServiceInterface'
export * from './User/UserApiOperations'
export * from './User/UserApiService'
export * from './User/UserApiServiceInterface'
export * from './WebSocket/WebSocketApiService'
@@ -0,0 +1,6 @@
import { Uuid } from '@standardnotes/common'
export type UserDeletionRequestParams = {
userUuid: Uuid
[additionalParam: string]: unknown
}
@@ -0,0 +1,7 @@
import { UserRequestType, Uuid } from '@standardnotes/common'
export type UserRequestRequestParams = {
userUuid: Uuid
requestType: UserRequestType
[additionalParam: string]: unknown
}
+1
View File
@@ -5,6 +5,7 @@ export * from './Subscription/SubscriptionInviteDeclineRequestParams'
export * from './Subscription/SubscriptionInviteListRequestParams'
export * from './Subscription/SubscriptionInviteRequestParams'
export * from './User/UserRegistrationRequestParams'
export * from './UserRequest/UserRequestRequestParams'
export * from './WebSocket/WebSocketConnectionTokenRequestParams'
export * from './Workspace/WorkspaceCreationRequestParams'
export * from './Workspace/WorkspaceInvitationAcceptingRequestParams'
@@ -0,0 +1,9 @@
import { Either } from '@standardnotes/common'
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
import { HttpResponse } from '../../Http/HttpResponse'
import { UserDeletionResponseBody } from './UserDeletionResponseBody'
export interface UserDeletionResponse extends HttpResponse {
data: Either<UserDeletionResponseBody, HttpErrorResponseBody>
}
@@ -0,0 +1,3 @@
export type UserDeletionResponseBody = {
message: string
}
@@ -0,0 +1,9 @@
import { Either } from '@standardnotes/common'
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
import { HttpResponse } from '../../Http/HttpResponse'
import { UserRequestResponseBody } from './UserRequestResponseBody'
export interface UserRequestResponse extends HttpResponse {
data: Either<UserRequestResponseBody, HttpErrorResponseBody>
}
@@ -0,0 +1,3 @@
export type UserRequestResponseBody = {
success: boolean
}
@@ -8,8 +8,12 @@ export * from './Subscription/SubscriptionInviteListResponse'
export * from './Subscription/SubscriptionInviteListResponseBody'
export * from './Subscription/SubscriptionInviteResponse'
export * from './Subscription/SubscriptionInviteResponseBody'
export * from './User/UserDeletionResponse'
export * from './User/UserDeletionResponseBody'
export * from './User/UserRegistrationResponse'
export * from './User/UserRegistrationResponseBody'
export * from './UserRequest/UserRequestResponse'
export * from './UserRequest/UserRequestResponseBody'
export * from './WebSocket/WebSocketConnectionTokenResponse'
export * from './WebSocket/WebSocketConnectionTokenResponseBody'
export * from './Workspace/WorkspaceCreationResponse'
@@ -1,5 +1,8 @@
import { Uuid } from '@standardnotes/common'
const UserPaths = {
register: '/v1/users',
deleteAccount: (userUuid: Uuid) => `/v1/users/${userUuid}`,
}
export const Paths = {
@@ -1,7 +1,7 @@
import { ProtocolVersion } from '@standardnotes/common'
import { ApiVersion } from '../../Api'
import { HttpServiceInterface } from '../../Http'
import { UserRegistrationResponse } from '../../Response'
import { UserDeletionResponse, UserRegistrationResponse } from '../../Response'
import { UserServer } from './UserServer'
describe('UserServer', () => {
@@ -14,6 +14,9 @@ describe('UserServer', () => {
httpService.post = jest.fn().mockReturnValue({
data: { user: { email: '[email protected]', uuid: '1-2-3' } },
} as jest.Mocked<UserRegistrationResponse>)
httpService.delete = jest.fn().mockReturnValue({
data: { message: 'Success' },
} as jest.Mocked<UserDeletionResponse>)
})
it('should register a user', async () => {
@@ -36,4 +39,16 @@ describe('UserServer', () => {
},
})
})
it('should delete a user', async () => {
const response = await createServer().deleteAccount({
userUuid: '1-2-3',
})
expect(response).toEqual({
data: {
message: 'Success',
},
})
})
})
@@ -1,5 +1,7 @@
import { HttpServiceInterface } from '../../Http/HttpServiceInterface'
import { UserDeletionRequestParams } from '../../Request/User/UserDeletionRequestParams'
import { UserRegistrationRequestParams } from '../../Request/User/UserRegistrationRequestParams'
import { UserDeletionResponse } from '../../Response/User/UserDeletionResponse'
import { UserRegistrationResponse } from '../../Response/User/UserRegistrationResponse'
import { Paths } from './Paths'
import { UserServerInterface } from './UserServerInterface'
@@ -7,6 +9,12 @@ import { UserServerInterface } from './UserServerInterface'
export class UserServer implements UserServerInterface {
constructor(private httpService: HttpServiceInterface) {}
async deleteAccount(params: UserDeletionRequestParams): Promise<UserDeletionResponse> {
const response = await this.httpService.delete(Paths.v1.deleteAccount(params.userUuid), params)
return response as UserDeletionResponse
}
async register(params: UserRegistrationRequestParams): Promise<UserRegistrationResponse> {
const response = await this.httpService.post(Paths.v1.register, params)
@@ -1,6 +1,9 @@
import { UserDeletionRequestParams } from '../../Request/User/UserDeletionRequestParams'
import { UserRegistrationRequestParams } from '../../Request/User/UserRegistrationRequestParams'
import { UserDeletionResponse } from '../../Response/User/UserDeletionResponse'
import { UserRegistrationResponse } from '../../Response/User/UserRegistrationResponse'
export interface UserServerInterface {
register(params: UserRegistrationRequestParams): Promise<UserRegistrationResponse>
deleteAccount(params: UserDeletionRequestParams): Promise<UserDeletionResponse>
}
@@ -0,0 +1,11 @@
import { Uuid } from '@standardnotes/common'
const UserRequestPaths = {
submitUserRequest: (userUuid: Uuid) => `/v1/users/${userUuid}/requests`,
}
export const Paths = {
v1: {
...UserRequestPaths,
},
}
@@ -0,0 +1,32 @@
import { UserRequestType } from '@standardnotes/common'
import { HttpServiceInterface } from '../../Http'
import { UserRequestResponse } from '../../Response/UserRequest/UserRequestResponse'
import { UserRequestServer } from './UserRequestServer'
describe('UserRequestServer', () => {
let httpService: HttpServiceInterface
const createServer = () => new UserRequestServer(httpService)
beforeEach(() => {
httpService = {} as jest.Mocked<HttpServiceInterface>
httpService.post = jest.fn().mockReturnValue({
data: { success: true },
} as jest.Mocked<UserRequestResponse>)
})
it('should submit a user request', async () => {
const response = await createServer().submitUserRequest({
userUuid: '1-2-3',
requestType: UserRequestType.ExitDiscount,
})
expect(response).toEqual({
data: {
success: true,
},
})
})
})
@@ -0,0 +1,16 @@
import { HttpServiceInterface } from '../../Http/HttpServiceInterface'
import { UserRequestRequestParams } from '../../Request/UserRequest/UserRequestRequestParams'
import { UserRequestResponse } from '../../Response/UserRequest/UserRequestResponse'
import { Paths } from './Paths'
import { UserRequestServerInterface } from './UserRequestServerInterface'
export class UserRequestServer implements UserRequestServerInterface {
constructor(private httpService: HttpServiceInterface) {}
async submitUserRequest(params: UserRequestRequestParams): Promise<UserRequestResponse> {
const response = await this.httpService.post(Paths.v1.submitUserRequest(params.userUuid), params)
return response as UserRequestResponse
}
}
@@ -0,0 +1,6 @@
import { UserRequestRequestParams } from '../../Request/UserRequest/UserRequestRequestParams'
import { UserRequestResponse } from '../../Response/UserRequest/UserRequestResponse'
export interface UserRequestServerInterface {
submitUserRequest(params: UserRequestRequestParams): Promise<UserRequestResponse>
}
+2
View File
@@ -2,6 +2,8 @@ export * from './Subscription/SubscriptionServer'
export * from './Subscription/SubscriptionServerInterface'
export * from './User/UserServer'
export * from './User/UserServerInterface'
export * from './UserRequest/UserRequestServer'
export * from './UserRequest/UserRequestServerInterface'
export * from './WebSocket/WebSocketServer'
export * from './WebSocket/WebSocketServerInterface'
export * from './Workspace/WorkspaceServer'
+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.
## [2.7.24](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/components-meta
## [2.7.23](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-01)
**Note:** Version bump only for package @standardnotes/components-meta
## [2.7.22](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-27)
**Note:** Version bump only for package @standardnotes/components-meta
@@ -1,7 +1,7 @@
{
"files": {
"main.js": "./static/js/main.js",
"main.css": "./static/css/main.245e3425.css",
"main.css": "./static/css/main.bbda6d78.css",
"static/media/material-icons-two-tone.woff": "./static/media/material-icons-two-tone..woff",
"static/media/material-icons-two-tone.woff2": "./static/media/material-icons-two-tone..woff2",
"static/media/material-icons-round.woff": "./static/media/material-icons-round..woff",
@@ -74,10 +74,10 @@
"static/media/KaTeX_Size3-Regular.woff2": "./static/media/KaTeX_Size3-Regular..woff2",
"index.html": "./index.html",
"main.js.map": "./static/js/main.js.map",
"main.245e3425.css.map": "./static/css/main.245e3425.css.map"
"main.bbda6d78.css.map": "./static/css/main.bbda6d78.css.map"
},
"entrypoints": [
"static/js/main.js",
"static/css/main.245e3425.css"
"static/css/main.bbda6d78.css"
]
}
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="A lightweight WYSIWYG markdown editor, derivated from Milkdown editor"/><link rel="apple-touch-icon" href="./logo192.png"/><link rel="manifest" href="./manifest.json"/><title>Markdown Visual</title><script defer="defer" src="./static/js/main.js"></script><link href="./static/css/main.245e3425.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="A lightweight WYSIWYG markdown editor, derivated from Milkdown editor"/><link rel="apple-touch-icon" href="./logo192.png"/><link rel="manifest" href="./manifest.json"/><title>Markdown Visual</title><script defer="defer" src="./static/js/main.js"></script><link href="./static/css/main.bbda6d78.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6 -6
View File
@@ -70,9 +70,9 @@
"binary": "b621bfd81829a205f2f02e85d446e277ad20e367b92676ec20b3ee59b1bfab3f"
},
"org.standardnotes.markdown-visual-editor": {
"version": "1.1.4",
"base64": "7d206437fca5c4f5b2a4a4ee5a9a29fdb3e2fbb1637ff1dbe962f00f48128993",
"binary": "6c396c45102a114b6d507ad24bdae38168baf780d77f66d0f7c12b25c89b7c57"
"version": "1.1.5",
"base64": "7aea4cbf43d8cb6411171d09c1cd7e0428d59ab53419b601011ccfeb747426a3",
"binary": "ad75788eee720990203f8443bdc8c0a171ec404ba3462d33f833937d6ba236a4"
},
"org.standardnotes.simple-task-editor": {
"version": "1.4.4",
@@ -80,9 +80,9 @@
"binary": "9df983a144b9686f4f58b03bf78bf1f84f53aea60251621a75586722bf576475"
},
"org.standardnotes.token-vault": {
"version": "2.2.6",
"base64": "52ab80192bdee708b4ded34590ed644d0bb41e6438d88e5a48dce0490b55dcac",
"binary": "27efe92ba9a345d94818fac8b46c3281ba0462fc5ed805df0e0052384e1e2826"
"version": "2.2.7",
"base64": "fd6ecde33b7135487a60d630813de8f8b4e5e0f06457c7dfda5bee28f3ea1113",
"binary": "88d1401384373ea8bc4b1c4669b34733e24d3692f7aa544b2d6f796de2275703"
},
"org.standardnotes.standard-sheets": {
"version": "1.5.1",
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/components-meta",
"version": "2.7.22",
"version": "2.7.24",
"private": true,
"author": "Standard Notes.",
"main": "dist",
@@ -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.1.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-01)
**Note:** Version bump only for package @standardnotes/markdown-visual
## [1.1.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-27)
**Note:** Version bump only for package @standardnotes/markdown-visual
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/markdown-visual",
"version": "1.1.4",
"version": "1.1.5",
"author": "Johnny Almonte <[email protected]>",
"description": "A lightweight WYSIWYG markdown editor for Standard Notes, derived from Milkdown.",
"keywords": [
@@ -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.
## [2.2.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-01)
**Note:** Version bump only for package @standardnotes/authenticator
## [2.2.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-27)
**Note:** Version bump only for package @standardnotes/authenticator
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/authenticator",
"version": "2.2.6",
"version": "2.2.7",
"main": "dist/dist.js",
"author": "Standard Notes",
"private": true,
+47
View File
@@ -3,6 +3,53 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.23.271](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-03)
### Bug Fixes
* **desktop:** editor column top padding on mac ([9ae0ce0](https://github.com/standardnotes/app/commit/9ae0ce0bfd78bedf3e8318aa56b8542dd81d5870))
## [3.23.270](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-03)
### Bug Fixes
* **desktop:** only add extra popover padding for small windows ([ac96e19](https://github.com/standardnotes/app/commit/ac96e197e00a7e7af1b771e46a178b0fa21d0f94))
* **desktop:** selected column top padding on small windows ([d6cafa1](https://github.com/standardnotes/app/commit/d6cafa1e739dd46e4cf465d8511aad2024ebe294))
## [3.23.269](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-03)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.268](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.267](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.266](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.265](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.264](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-01)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.263](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-01)
### Bug Fixes
* **mobile:** increase font sizes and other mobile-centric improvements ([#1907](https://github.com/standardnotes/app/issues/1907)) ([994f824](https://github.com/standardnotes/app/commit/994f824757e1143a4547c975b154fd84e3ebeedf))
## [3.23.262](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-31)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.261](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-31)
**Note:** Version bump only for package @standardnotes/desktop
@@ -111,7 +111,7 @@ async function configureWindow(remoteBridge: CrossProcessBridge) {
// For Mac inset window
const sheet = document.styleSheets[0]
if (isMacOS) {
sheet.insertRule('#navigation { padding-top: 25px !important; }', sheet.cssRules.length)
sheet.insertRule('#navigation-content { padding-top: 25px !important; }', sheet.cssRules.length)
}
if (isMacOS || useSystemMenuBar) {
@@ -122,7 +122,7 @@ async function configureWindow(remoteBridge: CrossProcessBridge) {
the app content height so its not overflowing */
sheet.insertRule('body { padding-top: var(--sn-desktop-titlebar-height); }', sheet.cssRules.length)
sheet.insertRule(
'[data-popover] { padding-top: calc(var(--sn-desktop-titlebar-height) + 0.5rem); }',
'@media screen and (max-width: 768px) { [data-popover] { padding-top: calc(var(--sn-desktop-titlebar-height) + 0.5rem); } }',
sheet.cssRules.length,
)
sheet.insertRule(
@@ -9,6 +9,12 @@
transition: 0.15s padding ease;
}
@media screen and (max-width: 768px) {
.mac-desktop .app-column.selected {
padding-top: 18px;
}
}
@media screen and (min-width: 768px) {
.mac-desktop #app.collapsed-notes.collapsed-navigation #editor-column {
padding-top: 18px;
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@standardnotes/desktop",
"main": "./app/dist/index.js",
"version": "3.23.261",
"version": "3.23.271",
"license": "AGPL-3.0-or-later",
"author": "Standard Notes.",
"private": true,
+10
View File
@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.19.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/encryption
# [1.19.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
### Features
* add sending user requests to process ([#1908](https://github.com/standardnotes/app/issues/1908)) ([b2faa81](https://github.com/standardnotes/app/commit/b2faa815e967a9e7052b3ce6955e967c6bc68864))
## [1.18.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-27)
**Note:** Version bump only for package @standardnotes/encryption
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/encryption",
"version": "1.18.8",
"version": "1.19.1",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -35,7 +35,7 @@
"typescript": "*"
},
"dependencies": {
"@standardnotes/common": "^1.39.0",
"@standardnotes/common": "^1.43.0",
"@standardnotes/models": "workspace:*",
"@standardnotes/responses": "workspace:*",
"@standardnotes/sncrypto-common": "workspace:*",
@@ -1,54 +1,67 @@
import { ProtocolVersion } from '@standardnotes/common'
import { KeyParamsOrigination, ProtocolVersion } from '@standardnotes/common'
import {
BackupFile,
DecryptedPayloadInterface,
EncryptedPayloadInterface,
ItemContent,
ItemsKeyInterface,
RootKeyInterface,
} from '@standardnotes/models'
import { ClientDisplayableError } from '@standardnotes/responses'
import { SNRootKeyParams } from '../../Keys/RootKey/RootKeyParams'
import { KeyedDecryptionSplit } from '../../Split/KeyedDecryptionSplit'
import { KeyedEncryptionSplit } from '../../Split/KeyedEncryptionSplit'
export interface EncryptionProviderInterface {
encryptSplitSingle(split: KeyedEncryptionSplit): Promise<EncryptedPayloadInterface>
encryptSplit(split: KeyedEncryptionSplit): Promise<EncryptedPayloadInterface[]>
decryptSplitSingle<
C extends ItemContent = ItemContent,
P extends DecryptedPayloadInterface<C> = DecryptedPayloadInterface<C>,
>(
split: KeyedDecryptionSplit,
): Promise<P | EncryptedPayloadInterface>
decryptSplit<
C extends ItemContent = ItemContent,
P extends DecryptedPayloadInterface<C> = DecryptedPayloadInterface<C>,
>(
split: KeyedDecryptionSplit,
): Promise<(P | EncryptedPayloadInterface)[]>
hasRootKeyEncryptionSource(): boolean
getKeyEmbeddedKeyParams(key: EncryptedPayloadInterface): SNRootKeyParams | undefined
computeRootKey(password: string, keyParams: SNRootKeyParams): Promise<RootKeyInterface>
/**
* @returns The versions that this library supports.
*/
supportedVersions(): ProtocolVersion[]
getUserVersion(): ProtocolVersion | undefined
/**
* Decrypts a backup file using user-inputted password
* @param password - The raw user password associated with this backup file
*/
decryptBackupFile(
file: BackupFile,
password?: string,
): Promise<ClientDisplayableError | (EncryptedPayloadInterface | DecryptedPayloadInterface)[]>
hasAccount(): boolean
decryptErroredPayloads(): Promise<void>
deleteWorkspaceSpecificKeyStateFromDevice(): Promise<void>
hasPasscode(): boolean
createRootKey(
identifier: string,
password: string,
origination: KeyParamsOrigination,
version?: ProtocolVersion,
): Promise<RootKeyInterface>
setNewRootKeyWrapper(wrappingKey: RootKeyInterface): Promise<void>
removePasscode(): Promise<void>
validateAccountPassword(password: string): Promise<
| {
valid: true
artifacts: {
rootKey: RootKeyInterface
}
}
| {
valid: boolean
}
>
createNewItemsKeyWithRollback(): Promise<() => Promise<void>>
reencryptItemsKeys(): Promise<void>
getSureDefaultItemsKey(): ItemsKeyInterface
getRootKeyParams(): Promise<SNRootKeyParams | undefined>
}
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.54.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
### Features
* add sending user requests to process ([#1908](https://github.com/standardnotes/app/issues/1908)) ([b2faa81](https://github.com/standardnotes/app/commit/b2faa815e967a9e7052b3ce6955e967c6bc68864))
## [1.53.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/features
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/features",
"version": "1.53.2",
"version": "1.54.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -26,7 +26,7 @@
},
"dependencies": {
"@standardnotes/auth": "^3.19.4",
"@standardnotes/common": "^1.39.0",
"@standardnotes/common": "^1.43.0",
"@standardnotes/security": "^1.2.0",
"reflect-metadata": "^0.1.13"
},
+10
View File
@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.25.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/filepicker
# [1.25.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
### Features
* add sending user requests to process ([#1908](https://github.com/standardnotes/app/issues/1908)) ([b2faa81](https://github.com/standardnotes/app/commit/b2faa815e967a9e7052b3ce6955e967c6bc68864))
## [1.24.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-27)
**Note:** Version bump only for package @standardnotes/filepicker
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/filepicker",
"version": "1.24.10",
"version": "1.25.1",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -32,7 +32,7 @@
"typescript": "*"
},
"dependencies": {
"@standardnotes/common": "^1.39.0",
"@standardnotes/common": "^1.43.0",
"@standardnotes/files": "workspace:*",
"@standardnotes/utils": "workspace:*",
"@types/wicg-file-system-access": "^2020.9.5",
+10
View File
@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.12.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/files
# [1.12.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
### Features
* add sending user requests to process ([#1908](https://github.com/standardnotes/app/issues/1908)) ([b2faa81](https://github.com/standardnotes/app/commit/b2faa815e967a9e7052b3ce6955e967c6bc68864))
## [1.11.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-27)
**Note:** Version bump only for package @standardnotes/files
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files",
"version": "1.11.10",
"version": "1.12.1",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -30,7 +30,7 @@
"ts-jest": "^28.0.5"
},
"dependencies": {
"@standardnotes/common": "^1.39.0",
"@standardnotes/common": "^1.43.0",
"@standardnotes/encryption": "workspace:*",
"@standardnotes/models": "workspace:*",
"@standardnotes/responses": "workspace:*",
+57
View File
@@ -3,6 +3,63 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.45.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-03)
**Note:** Version bump only for package @standardnotes/mobile
## [3.45.19](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-03)
### Bug Fixes
* **mobile:** disable pinch zoom on mobile app UI ([dc4530b](https://github.com/standardnotes/app/commit/dc4530b2f33057ec3d44a94b28dc0407656d4098))
## [3.45.18](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-03)
**Note:** Version bump only for package @standardnotes/mobile
## [3.45.17](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/mobile
## [3.45.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/mobile
## [3.45.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/mobile
## [3.45.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/mobile
## [3.45.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-01)
**Note:** Version bump only for package @standardnotes/mobile
## [3.45.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-01)
### Bug Fixes
* **mobile:** increase font sizes and other mobile-centric improvements ([#1907](https://github.com/standardnotes/app/issues/1907)) ([994f824](https://github.com/standardnotes/app/commit/994f824757e1143a4547c975b154fd84e3ebeedf))
## [3.45.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-31)
### Bug Fixes
* **mobile:** bump minimum android sdk to 28 (9.0) ([50b0db3](https://github.com/standardnotes/app/commit/50b0db3baa4f27de3e7c13bbb59d9e33a360d949))
## [3.45.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-31)
### Bug Fixes
* **mobile:** decrease iOS deployment target to 13 ([8b25c01](https://github.com/standardnotes/app/commit/8b25c01551ffde67a41d87ae79fd21d46a10eff3))
* **mobile:** increase iOS deployment target to 14 ([50182fa](https://github.com/standardnotes/app/commit/50182fad4ff635fe1c54c8880fb82ef3f3c9c434))
## [3.45.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-31)
**Note:** Version bump only for package @standardnotes/mobile
## [3.45.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-31)
**Note:** Version bump only for package @standardnotes/mobile
+1 -3
View File
@@ -5,7 +5,7 @@ buildscript {
ext {
buildToolsVersion = "30.0.3"
minSdkVersion = 21
minSdkVersion = 28
compileSdkVersion = 30
targetSdkVersion = 30
androidXCore = "1.6.0"
@@ -15,7 +15,6 @@ buildscript {
google()
mavenLocal()
mavenCentral()
jcenter()
}
dependencies {
classpath('com.android.tools.build:gradle:7.1.2')
@@ -45,7 +44,6 @@ allprojects {
}
}
google()
jcenter()
maven {
// All of Detox' artifacts are provided via the npm module
url "$rootDir/../node_modules/detox/Detox-android"
@@ -4,7 +4,7 @@
<head>
<meta charset="utf-8" />
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
<meta content="viewport-fit=cover, width=device-width, initial-scale=1" name="viewport" />
<meta content="viewport-fit=cover, width=device-width, initial-scale=1, maximum-scale=1.0" name="viewport" />
<meta content="#ffffff" name="theme-color" />
<link rel="stylesheet" href="web-src/app.css" />
<script>
@@ -23,4 +23,4 @@
<body>
</body>
</html>
</html>
@@ -11,7 +11,7 @@
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
1C2EEB3B45F4EB07AC795C77 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
1C2EEB3B45F4EB07AC795C77 /* (null) in Frameworks */ = {isa = PBXBuildFile; };
33BB1B14071EBE5978EBF3A8 /* libPods-StandardNotes-StandardNotesTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 04FCB5A3A3387CA3CFC82AA3 /* libPods-StandardNotes-StandardNotesTests.a */; };
BC8DEA834BF198E8511F04FF /* libPods-StandardNotesDev.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F2D747BE02C2A1BCFEEFD1 /* libPods-StandardNotesDev.a */; };
CD7D5ECA27800609005FE1BF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CD7D5EC927800608005FE1BF /* LaunchScreen.storyboard */; };
@@ -86,7 +86,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1C2EEB3B45F4EB07AC795C77 /* BuildFile in Frameworks */,
1C2EEB3B45F4EB07AC795C77 /* (null) in Frameworks */,
DD3D1CE428EC1C8BA0C49211 /* libPods-StandardNotes.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -754,7 +754,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
/usr/lib/swift,
"$(inherited)",
@@ -812,7 +812,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
/usr/lib/swift,
"$(inherited)",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/mobile",
"version": "3.45.8",
"version": "3.45.20",
"author": "Standard Notes.",
"private": true,
"license": "AGPL-3.0-or-later",
@@ -35,7 +35,7 @@
"react": "17.0.2",
"react-native": "0.67.4",
"react-native-file-viewer": "^2.1.5",
"react-native-fingerprint-scanner": "standardnotes/react-native-fingerprint-scanner#0f9c1f6712ee0c1a2908fe7e589c72151d143c48",
"react-native-fingerprint-scanner": "standardnotes/react-native-fingerprint-scanner#b55d1c0ca627a87a130f758603f12911fbac200f",
"react-native-flag-secure-android": "standardnotes/react-native-flag-secure-android#cb08e74583c22a5d912842459b35ebbbb4bcd852",
"react-native-fs": "^2.19.0",
"react-native-keychain": "standardnotes/react-native-keychain#d277d360494cbd02be4accb4a360772a8e0e97b6",
+29 -1
View File
@@ -58,12 +58,34 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
device.reloadStatusBarStyle(false)
})
const keyboardWillChangeFrame = Keyboard.addListener('keyboardWillChangeFrame', (e) => {
webViewRef.current?.postMessage(
JSON.stringify({
reactNativeEvent: ReactNativeToWebEvent.KeyboardFrameWillChange,
messageType: 'event',
messageData: { height: e.endCoordinates.height, contentHeight: e.endCoordinates.screenY },
}),
)
})
const keyboardDidChangeFrame = Keyboard.addListener('keyboardDidChangeFrame', (e) => {
webViewRef.current?.postMessage(
JSON.stringify({
reactNativeEvent: ReactNativeToWebEvent.KeyboardFrameDidChange,
messageType: 'event',
messageData: { height: e.endCoordinates.height, contentHeight: e.endCoordinates.screenY },
}),
)
})
return () => {
removeStateServiceListener()
removeBackHandlerServiceListener()
removeColorSchemeServiceListener()
keyboardShowListener.remove()
keyboardHideListener.remove()
keyboardWillChangeFrame.remove()
keyboardDidChangeFrame.remove()
}
}, [webViewRef, stateService, device, androidBackHandlerService, colorSchemeService])
@@ -198,7 +220,7 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
const onFunctionMessage = async (functionName: string, messageId: string, args: any) => {
const returnValue = await (device as any)[functionName](...args)
if (LoggingEnabled) {
if (LoggingEnabled && functionName !== 'consoleLog') {
console.log(`Native device function ${functionName} called`)
}
webViewRef.current?.postMessage(JSON.stringify({ messageId, returnValue, messageType: 'reply' }))
@@ -253,6 +275,12 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
injectedJavaScriptBeforeContentLoaded={injectedJS}
bounces={false}
keyboardDisplayRequiresUserAction={false}
scalesPageToFit={true}
/**
* This disables the global window scroll but keeps scroll within div elements like lists and textareas.
* This is needed to prevent the keyboard from pushing the webview up and down when it appears and disappears.
*/
scrollEnabled={false}
/>
)
}
+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.34.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
### Features
* dedicated files layout ([#1928](https://github.com/standardnotes/app/issues/1928)) ([dd821c9](https://github.com/standardnotes/app/commit/dd821c95e61c8cd82317ad9fb3788daff7241942))
# [1.33.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
### Features
* add sending user requests to process ([#1908](https://github.com/standardnotes/app/issues/1908)) ([b2faa81](https://github.com/standardnotes/app/commit/b2faa815e967a9e7052b3ce6955e967c6bc68864))
# [1.32.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-27)
### Features
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/models",
"version": "1.32.0",
"version": "1.34.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -32,7 +32,7 @@
"typescript": "*"
},
"dependencies": {
"@standardnotes/common": "^1.39.0",
"@standardnotes/common": "^1.43.0",
"@standardnotes/features": "workspace:*",
"@standardnotes/responses": "workspace:*",
"@standardnotes/utils": "workspace:*",
@@ -17,4 +17,5 @@ export interface TagPreferences {
customNoteTitleFormat?: string
editorIdentifier?: FeatureIdentifier | string
entryMode?: 'normal' | 'daily'
panelWidth?: number
}
+48
View File
@@ -3,6 +3,54 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.202](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-03)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.201](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-03)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.200](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-03)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.199](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.198](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.197](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.196](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.195](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-01)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.194](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-01)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.193](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-31)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.192](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-31)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.191](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-31)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.190](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-31)
**Note:** Version bump only for package @standardnotes/releases
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/releases",
"version": "1.3.190",
"version": "1.3.202",
"license": "AGPL-3.0-or-later",
"main": "dist/releases.json",
"types": "dist/index.d.ts",
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.12.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
### Features
* add sending user requests to process ([#1908](https://github.com/standardnotes/app/issues/1908)) ([b2faa81](https://github.com/standardnotes/app/commit/b2faa815e967a9e7052b3ce6955e967c6bc68864))
## [1.11.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/responses
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/responses",
"version": "1.11.2",
"version": "1.12.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -31,7 +31,7 @@
"ts-jest": "^28.0.5"
},
"dependencies": {
"@standardnotes/common": "^1.39.0",
"@standardnotes/common": "^1.43.0",
"@standardnotes/features": "workspace:*",
"@standardnotes/security": "^1.1.0",
"reflect-metadata": "^0.1.13"
+28
View File
@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.42.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-03)
### Features
* add sending user requests from UI ([#1927](https://github.com/standardnotes/app/issues/1927)) ([7ead0f6](https://github.com/standardnotes/app/commit/7ead0f655bb2572e5805dd26c297d520949d661a))
# [1.41.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
### Features
* prioritize loading latest selected items ([#1930](https://github.com/standardnotes/app/issues/1930)) ([a6ef658](https://github.com/standardnotes/app/commit/a6ef658daef9a01f5ddacc967fe30d22f580799a))
## [1.40.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/services
# [1.40.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
### Features
* add sending user requests to process ([#1908](https://github.com/standardnotes/app/issues/1908)) ([b2faa81](https://github.com/standardnotes/app/commit/b2faa815e967a9e7052b3ce6955e967c6bc68864))
## [1.39.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-01)
### Bug Fixes
* **mobile:** increase font sizes and other mobile-centric improvements ([#1907](https://github.com/standardnotes/app/issues/1907)) ([994f824](https://github.com/standardnotes/app/commit/994f824757e1143a4547c975b154fd84e3ebeedf))
## [1.39.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-28)
### Bug Fixes
+4 -4
View File
@@ -10,10 +10,10 @@ module.exports = {
},
coverageThreshold: {
global: {
branches: 9,
functions: 10,
lines: 16,
statements: 16
branches: 6,
functions: 9,
lines: 13,
statements: 13
}
}
};
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/services",
"version": "1.39.1",
"version": "1.42.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -26,12 +26,13 @@
"dependencies": {
"@standardnotes/api": "workspace:^",
"@standardnotes/auth": "^3.19.4",
"@standardnotes/common": "^1.39.0",
"@standardnotes/common": "^1.43.0",
"@standardnotes/encryption": "workspace:^",
"@standardnotes/files": "workspace:^",
"@standardnotes/models": "workspace:^",
"@standardnotes/responses": "workspace:*",
"@standardnotes/security": "^1.2.0",
"@standardnotes/sncrypto-common": "workspace:^",
"@standardnotes/utils": "workspace:*",
"reflect-metadata": "^0.1.13"
},
@@ -16,7 +16,7 @@ import { StorageValueModes } from '../Storage/StorageTypes'
import { DeinitMode } from './DeinitMode'
import { DeinitSource } from './DeinitSource'
import { UserClientInterface } from './UserClientInterface'
import { UserClientInterface } from '../User/UserClientInterface'
export interface ApplicationInterface {
deinit(mode: DeinitMode, source: DeinitSource): void
@@ -1,9 +0,0 @@
import { DeinitSource } from './DeinitSource'
export interface UserClientInterface {
deleteAccount(): Promise<{
error: boolean
message?: string
}>
signOut(force?: boolean, source?: DeinitSource): Promise<void>
}
@@ -11,6 +11,8 @@ export interface WebApplicationInterface extends ApplicationInterface {
handleMobileLosingFocusEvent(): Promise<void>
handleMobileResumingFromBackgroundEvent(): Promise<void>
handleMobileColorSchemeChangeEvent(): void
handleMobileKeyboardWillChangeFrameEvent(frame: { height: number; contentHeight: number }): void
handleMobileKeyboardDidChangeFrameEvent(frame: { height: number; contentHeight: number }): void
isNativeMobileWeb(): boolean
mobileDevice(): MobileDeviceInterface
handleAndroidBackButtonPressed(): void
@@ -1,6 +1,9 @@
import { ChallengeModalTitle, ChallengeStrings } from '../Api/Messages'
import { assertUnreachable } from '@standardnotes/utils'
import { ChallengeValidation, ChallengeReason, ChallengeInterface, ChallengePrompt } from '@standardnotes/services'
import { ChallengeModalTitle, ChallengeStrings } from '../Strings/Messages'
import { ChallengeInterface } from './ChallengeInterface'
import { ChallengePrompt } from './Prompt/ChallengePrompt'
import { ChallengeReason } from './Types/ChallengeReason'
import { ChallengeValidation } from './Types/ChallengeValidation'
/**
* A challenge is a stateless description of what the client needs to provide
@@ -1,3 +1,5 @@
import { RootKeyInterface } from '@standardnotes/models'
import { AbstractService } from '../Service/AbstractService'
import { ChallengeInterface } from './ChallengeInterface'
import { ChallengePromptInterface } from './Prompt/ChallengePromptInterface'
@@ -10,7 +12,6 @@ export interface ChallengeServiceInterface extends AbstractService {
* For non-validated challenges, will resolve when the first value is submitted.
*/
promptForChallengeResponse(challenge: ChallengeInterface): Promise<ChallengeResponseInterface | undefined>
createChallenge(
prompts: ChallengePromptInterface[],
reason: ChallengeReason,
@@ -18,6 +19,19 @@ export interface ChallengeServiceInterface extends AbstractService {
heading?: string,
subheading?: string,
): ChallengeInterface
completeChallenge(challenge: ChallengeInterface): void
getWrappingKeyIfApplicable(passcode?: string): Promise<
| {
canceled?: undefined
wrappingKey?: undefined
}
| {
canceled: boolean
wrappingKey?: undefined
}
| {
wrappingKey: RootKeyInterface
canceled?: undefined
}
>
}
@@ -1,3 +1,4 @@
export * from './Challenge'
export * from './ChallengeInterface'
export * from './ChallengeResponseInterface'
export * from './ChallengeServiceInterface'
@@ -6,4 +6,6 @@ export enum WebAppEvent {
PanelResized = 'PanelResized',
WindowDidFocus = 'WindowDidFocus',
WindowDidBlur = 'WindowDidBlur',
MobileKeyboardDidChangeFrame = 'MobileKeyboardDidChangeFrame',
MobileKeyboardWillChangeFrame = 'MobileKeyboardWillChangeFrame',
}
@@ -44,50 +44,22 @@ export interface ItemManagerInterface extends AbstractService {
contentType: ContentType | ContentType[],
callback: ItemManagerChangeObserverCallback<I>,
): () => void
/**
* Marks the item as deleted and needing sync.
*/
setItemToBeDeleted(itemToLookupUuidFor: DecryptedItemInterface, source?: PayloadEmitSource): Promise<void>
setItemsToBeDeleted(itemsToLookupUuidsFor: DecryptedItemInterface[]): Promise<void>
setItemsDirty(
itemsToLookupUuidsFor: DecryptedItemInterface[],
isUserModified?: boolean,
): Promise<DecryptedItemInterface[]>
get items(): DecryptedItemInterface[]
/**
* Inserts the item as-is by reading its payload value. This function will not
* modify item in any way (such as marking it as dirty). It is up to the caller
* to pass in a dirtied item if that is their intention.
*/
insertItem(item: DecryptedItemInterface): Promise<DecryptedItemInterface>
emitItemFromPayload(payload: DecryptedPayloadInterface, source: PayloadEmitSource): Promise<DecryptedItemInterface>
getItems<T extends DecryptedItemInterface>(contentType: ContentType | ContentType[]): T[]
/**
* Returns all non-deleted items keys
*/
getDisplayableItemsKeys(): ItemsKeyInterface[]
/**
* Creates an item and conditionally maps it and marks it as dirty.
* @param needsSync - Whether to mark the item as needing sync
*/
createItem<T extends DecryptedItemInterface, C extends ItemContent = ItemContent>(
contentType: ContentType,
content: C,
needsSync?: boolean,
): Promise<T>
/**
* Create an unmanaged item that can later be inserted via `insertItem`
*/
createTemplateItem<
C extends ItemContent = ItemContent,
I extends DecryptedItemInterface<C> = DecryptedItemInterface<C>,
@@ -96,12 +68,6 @@ export interface ItemManagerInterface extends AbstractService {
content?: C,
override?: Partial<DecryptedPayload<C>>,
): I
/**
* Consumers wanting to modify an item should run it through this block,
* so that data is properly mapped through our function, and latest state
* is properly reconciled.
*/
changeItem<
M extends DecryptedItemMutator = DecryptedItemMutator,
I extends DecryptedItemInterface = DecryptedItemInterface,
@@ -112,7 +78,6 @@ export interface ItemManagerInterface extends AbstractService {
emitSource?: PayloadEmitSource,
payloadSourceKey?: string,
): Promise<I>
changeItemsKey(
itemToLookupUuidFor: ItemsKeyInterface,
mutate: (mutator: ItemsKeyMutatorInterface) => void,
@@ -120,16 +85,15 @@ export interface ItemManagerInterface extends AbstractService {
emitSource?: PayloadEmitSource,
payloadSourceKey?: string,
): Promise<ItemsKeyInterface>
itemsMatchingPredicate<T extends DecryptedItemInterface>(
contentType: ContentType,
predicate: PredicateInterface<T>,
): T[]
itemsMatchingPredicates<T extends DecryptedItemInterface>(
contentType: ContentType,
predicates: PredicateInterface<T>[],
): T[]
subItemsMatchingPredicates<T extends DecryptedItemInterface>(items: T[], predicates: PredicateInterface<T>[]): T[]
removeAllItemsFromMemory(): Promise<void>
getDirtyItems(): (DecryptedItemInterface | DeletedItemInterface)[]
}
@@ -0,0 +1,4 @@
export enum MobileUnlockTiming {
Immediately = 'immediately',
OnQuit = 'on-quit',
}
@@ -1,6 +1,7 @@
import { ChallengeReason } from '@standardnotes/services'
import { DecryptedItem } from '@standardnotes/models'
import { TimingDisplayOption, MobileUnlockTiming } from './MobileUnlockTiming'
import { ChallengeReason } from '../Challenge'
import { MobileUnlockTiming } from './MobileUnlockTiming'
import { TimingDisplayOption } from './TimingDisplayOption'
export interface ProtectionsClientInterface {
authorizeProtectedActionForItems<T extends DecryptedItem>(files: T[], challengeReason: ChallengeReason): Promise<T[]>
@@ -16,4 +17,11 @@ export interface ProtectionsClientInterface {
hasBiometricsEnabled(): boolean
enableBiometrics(): boolean
disableBiometrics(): Promise<boolean>
authorizeAction(
reason: ChallengeReason,
dto: { fallBackToAccountPassword: boolean; requireAccountPassword: boolean; forcePrompt: boolean },
): Promise<boolean>
authorizeAddingPasscode(): Promise<boolean>
authorizeRemovingPasscode(): Promise<boolean>
authorizeChangingPasscode(): Promise<boolean>
}
@@ -1,7 +1,4 @@
export enum MobileUnlockTiming {
Immediately = 'immediately',
OnQuit = 'on-quit',
}
import { MobileUnlockTiming } from './MobileUnlockTiming'
export type TimingDisplayOption = {
title: string
@@ -0,0 +1,9 @@
import { AnyKeyParamsContent } from '@standardnotes/common'
import { RootKeyInterface } from '@standardnotes/models'
import { HttpResponse } from '@standardnotes/responses'
export type SessionManagerResponse = {
response: HttpResponse
rootKey?: RootKeyInterface
keyParams?: AnyKeyParamsContent
}
@@ -0,0 +1,34 @@
import { UserRegistrationResponseBody } from '@standardnotes/api'
import { ProtocolVersion } from '@standardnotes/common'
import { RootKeyInterface } from '@standardnotes/models'
import { ClientDisplayableError, HttpResponse, SignInResponse, User } from '@standardnotes/responses'
import { Base64String } from '@standardnotes/sncrypto-common'
import { SessionManagerResponse } from './SessionManagerResponse'
export interface SessionsClientInterface {
createDemoShareToken(): Promise<Base64String | ClientDisplayableError>
populateSessionFromDemoShareToken(token: Base64String): Promise<void>
getUser(): User | undefined
register(email: string, password: string, ephemeral: boolean): Promise<UserRegistrationResponseBody>
signIn(
email: string,
password: string,
strict: boolean,
ephemeral: boolean,
minAllowedVersion?: ProtocolVersion,
): Promise<SessionManagerResponse>
getSureUser(): User
bypassChecksAndSignInWithRootKey(
email: string,
rootKey: RootKeyInterface,
ephemeral: boolean,
): Promise<SignInResponse | HttpResponse>
signOut(): Promise<void>
changeCredentials(parameters: {
currentServerPassword: string
newRootKey: RootKeyInterface
wrappingKey?: RootKeyInterface
newEmail?: string
}): Promise<SessionManagerResponse>
}
@@ -38,6 +38,7 @@ export enum StorageKey {
ExperimentalFeatures = 'experimental_features',
DeinitMode = 'deinit_mode',
CodeVerifier = 'code_verifier',
LaunchPriorityUuids = 'launch_priority_uuids',
}
export enum NonwrappedStorageKey {
@@ -1,16 +1,15 @@
import { PayloadInterface, RootKeyInterface } from '@standardnotes/models'
import { StorageValueModes } from './StorageTypes'
import { FullyFormedPayloadInterface, PayloadInterface, RootKeyInterface } from '@standardnotes/models'
import { StoragePersistencePolicies, StorageValueModes } from './StorageTypes'
export interface StorageServiceInterface {
getValue<T>(key: string, mode?: StorageValueModes, defaultValue?: T): T
canDecryptWithKey(key: RootKeyInterface): Promise<boolean>
savePayload(payload: PayloadInterface): Promise<void>
savePayloads(decryptedPayloads: PayloadInterface[]): Promise<void>
setValue(key: string, value: unknown, mode?: StorageValueModes): void
removeValue(key: string, mode?: StorageValueModes): Promise<void>
setPersistencePolicy(persistencePolicy: StoragePersistencePolicies): Promise<void>
clearAllData(): Promise<void>
forceDeletePayloads(payloads: FullyFormedPayloadInterface[]): Promise<void>
clearAllPayloads(): Promise<void>
}
@@ -1,7 +1,14 @@
/* istanbul ignore file */
import { FullyFormedPayloadInterface } from '@standardnotes/models'
import { SyncOptions } from './SyncOptions'
export interface SyncServiceInterface {
sync(options?: Partial<SyncOptions>): Promise<unknown>
resetSyncState(): void
markAllItemsAsNeedingSyncAndPersist(): Promise<void>
downloadFirstSync(waitTimeOnFailureMs: number, otherSyncOptions?: Partial<SyncOptions>): Promise<void>
persistPayloads(payloads: FullyFormedPayloadInterface[]): Promise<void>
lockSyncing(): void
unlockSyncing(): void
}
@@ -0,0 +1,11 @@
import { UserRequestType } from '@standardnotes/common'
import { DeinitSource } from '../Application/DeinitSource'
export interface UserClientInterface {
deleteAccount(): Promise<{
error: boolean
message?: string
}>
signOut(force?: boolean, source?: DeinitSource): Promise<void>
submitUserRequest(requestType: UserRequestType): Promise<boolean>
}
@@ -0,0 +1,92 @@
import { UserApiServiceInterface } from '@standardnotes/api'
import { UserRequestType } from '@standardnotes/common'
import { EncryptionProviderInterface } from '@standardnotes/encryption'
import { User } from '@standardnotes/responses'
import {
AlertService,
ChallengeServiceInterface,
InternalEventBusInterface,
ItemManagerInterface,
ProtectionsClientInterface,
} from '..'
import { SessionsClientInterface } from '../Session/SessionsClientInterface'
import { StorageServiceInterface } from '../Storage/StorageServiceInterface'
import { SyncServiceInterface } from '../Sync/SyncServiceInterface'
import { UserService } from './UserService'
describe('UserService', () => {
let sessionManager: SessionsClientInterface
let syncService: SyncServiceInterface
let storageService: StorageServiceInterface
let itemManager: ItemManagerInterface
let protocolService: EncryptionProviderInterface
let alertService: AlertService
let challengeService: ChallengeServiceInterface
let protectionService: ProtectionsClientInterface
let userApiService: UserApiServiceInterface
let internalEventBus: InternalEventBusInterface
const createService = () =>
new UserService(
sessionManager,
syncService,
storageService,
itemManager,
protocolService,
alertService,
challengeService,
protectionService,
userApiService,
internalEventBus,
)
beforeEach(() => {
sessionManager = {} as jest.Mocked<SessionsClientInterface>
sessionManager.getSureUser = jest.fn().mockReturnValue({ uuid: '1-2-3' } as jest.Mocked<User>)
syncService = {} as jest.Mocked<SyncServiceInterface>
storageService = {} as jest.Mocked<StorageServiceInterface>
itemManager = {} as jest.Mocked<ItemManagerInterface>
protocolService = {} as jest.Mocked<EncryptionProviderInterface>
alertService = {} as jest.Mocked<AlertService>
challengeService = {} as jest.Mocked<ChallengeServiceInterface>
protectionService = {} as jest.Mocked<ProtectionsClientInterface>
userApiService = {} as jest.Mocked<UserApiServiceInterface>
internalEventBus = {} as jest.Mocked<InternalEventBusInterface>
})
it('should submit a user request to the server', async () => {
userApiService.submitUserRequest = jest.fn().mockReturnValue({ data: { success: true } })
expect(await createService().submitUserRequest(UserRequestType.ExitDiscount)).toBeTruthy()
})
it('should indicate error if submit a user request to the server fails', async () => {
userApiService.submitUserRequest = jest.fn().mockReturnValue({ data: { success: false } })
expect(await createService().submitUserRequest(UserRequestType.ExitDiscount)).toBeFalsy()
})
it('should indicate error if submit a user request to the server fails with an error on server side', async () => {
userApiService.submitUserRequest = jest.fn().mockReturnValue({ data: { error: { message: 'fail' } } })
expect(await createService().submitUserRequest(UserRequestType.ExitDiscount)).toBeFalsy()
})
it('should indicate error if submitting a user request throws an exception', async () => {
userApiService.submitUserRequest = jest.fn().mockImplementation(() => {
throw new Error('Oops')
})
expect(await createService().submitUserRequest(UserRequestType.ExitDiscount)).toBeFalsy()
})
})
@@ -1,32 +1,29 @@
import { Challenge } from '../Challenge'
import { ChallengeService } from '../Challenge/ChallengeService'
import { SNRootKey, SNRootKeyParams } from '@standardnotes/encryption'
import { EncryptionProviderInterface, SNRootKey, SNRootKeyParams } from '@standardnotes/encryption'
import { HttpResponse, SignInResponse, User } from '@standardnotes/responses'
import { ItemManager } from '@Lib/Services/Items/ItemManager'
import { KeyParamsOrigination } from '@standardnotes/common'
import { KeyParamsOrigination, UserRequestType } from '@standardnotes/common'
import { UuidGenerator } from '@standardnotes/utils'
import { UserApiServiceInterface, UserRegistrationResponseBody } from '@standardnotes/api'
import * as Messages from '../Strings/Messages'
import { InfoStrings } from '../Strings/InfoStrings'
import { SyncServiceInterface } from '../Sync/SyncServiceInterface'
import { StorageServiceInterface } from '../Storage/StorageServiceInterface'
import { ItemManagerInterface } from '../Item/ItemManagerInterface'
import { AlertService } from '../Alert/AlertService'
import {
AbstractService,
AlertService,
Challenge,
ChallengePrompt,
ChallengeReason,
ChallengeServiceInterface,
ChallengeValidation,
DeinitSource,
InternalEventBusInterface,
UserClientInterface,
StoragePersistencePolicies,
EncryptionService,
} from '@standardnotes/services'
import { SNApiService } from './../Api/ApiService'
import { SNProtectionService } from '../Protection/ProtectionService'
import { SNSessionManager, MINIMUM_PASSWORD_LENGTH } from '../Session/SessionManager'
import { DiskStorageService } from '@Lib/Services/Storage/DiskStorageService'
import { SNSyncService } from '../Sync/SyncService'
import { Strings } from '../../Strings/index'
import { UuidGenerator } from '@standardnotes/utils'
import * as Messages from '../Api/Messages'
import { UserRegistrationResponseBody } from '@standardnotes/api'
const MINIMUM_PASSCODE_LENGTH = 1
} from '../Challenge'
import { InternalEventBusInterface } from '../Internal/InternalEventBusInterface'
import { AbstractService } from '../Service/AbstractService'
import { UserClientInterface } from './UserClientInterface'
import { DeinitSource } from '../Application/DeinitSource'
import { StoragePersistencePolicies } from '../Storage/StorageTypes'
import { SessionsClientInterface } from '../Session/SessionsClientInterface'
import { ProtectionsClientInterface } from '../Protection/ProtectionClientInterface'
export type CredentialsChangeFunctionResponse = { error?: { message: string } }
export type AccountServiceResponse = HttpResponse
@@ -44,16 +41,19 @@ export class UserService extends AbstractService<AccountEvent, AccountEventData>
private signingIn = false
private registering = false
private readonly MINIMUM_PASSCODE_LENGTH = 1
private readonly MINIMUM_PASSWORD_LENGTH = 8
constructor(
private sessionManager: SNSessionManager,
private syncService: SNSyncService,
private storageService: DiskStorageService,
private itemManager: ItemManager,
private protocolService: EncryptionService,
private sessionManager: SessionsClientInterface,
private syncService: SyncServiceInterface,
private storageService: StorageServiceInterface,
private itemManager: ItemManagerInterface,
private protocolService: EncryptionProviderInterface,
private alertService: AlertService,
private challengeService: ChallengeService,
private protectionService: SNProtectionService,
private apiService: SNApiService,
private challengeService: ChallengeServiceInterface,
private protectionService: ProtectionsClientInterface,
private userApiService: UserApiServiceInterface,
protected override internalEventBus: InternalEventBusInterface,
) {
super(internalEventBus)
@@ -69,7 +69,7 @@ export class UserService extends AbstractService<AccountEvent, AccountEventData>
;(this.alertService as unknown) = undefined
;(this.challengeService as unknown) = undefined
;(this.protectionService as unknown) = undefined
;(this.apiService as unknown) = undefined
;(this.userApiService as unknown) = undefined
}
/**
@@ -204,7 +204,9 @@ export class UserService extends AbstractService<AccountEvent, AccountEventData>
}> {
if (
!(await this.protectionService.authorizeAction(ChallengeReason.DeleteAccount, {
fallBackToAccountPassword: true,
requireAccountPassword: true,
forcePrompt: false,
}))
) {
return {
@@ -214,23 +216,41 @@ export class UserService extends AbstractService<AccountEvent, AccountEventData>
}
const uuid = this.sessionManager.getSureUser().uuid
const response = await this.apiService.deleteAccount(uuid)
if (response.error) {
const response = await this.userApiService.deleteAccount(uuid)
if (response.data.error) {
return {
error: true,
message: response.error.message,
message: response.data.error.message,
}
}
await this.signOut(true)
void this.alertService.alert(Strings.Info.AccountDeleted)
void this.alertService.alert(InfoStrings.AccountDeleted)
return {
error: false,
}
}
async submitUserRequest(requestType: UserRequestType): Promise<boolean> {
const userUuid = this.sessionManager.getSureUser().uuid
try {
const result = await this.userApiService.submitUserRequest({
userUuid,
requestType,
})
if (result.data.error) {
return false
}
return result.data.success
} catch (error) {
return false
}
}
/**
* A sign in request that occurs while the user was previously signed in, to correct
* for missing keys or storage values. Unlike regular sign in, this doesn't worry about
@@ -239,7 +259,11 @@ export class UserService extends AbstractService<AccountEvent, AccountEventData>
public async correctiveSignIn(rootKey: SNRootKey): Promise<HttpResponse | SignInResponse> {
this.lockSyncing()
const response = await this.sessionManager.bypassChecksAndSignInWithRootKey(rootKey.keyParams.identifier, rootKey)
const response = await this.sessionManager.bypassChecksAndSignInWithRootKey(
rootKey.keyParams.identifier,
rootKey,
false,
)
if (!response.error) {
await this.notifyEvent(AccountEvent.SignedInOrRegistered)
@@ -381,7 +405,7 @@ export class UserService extends AbstractService<AccountEvent, AccountEventData>
}
public async addPasscode(passcode: string): Promise<boolean> {
if (passcode.length < MINIMUM_PASSCODE_LENGTH) {
if (passcode.length < this.MINIMUM_PASSCODE_LENGTH) {
return false
}
if (!(await this.protectionService.authorizeAddingPasscode())) {
@@ -424,7 +448,7 @@ export class UserService extends AbstractService<AccountEvent, AccountEventData>
newPasscode: string,
origination = KeyParamsOrigination.PasscodeChange,
): Promise<boolean> {
if (newPasscode.length < MINIMUM_PASSCODE_LENGTH) {
if (newPasscode.length < this.MINIMUM_PASSCODE_LENGTH) {
return false
}
if (!(await this.protectionService.authorizeChangingPasscode())) {
@@ -501,9 +525,9 @@ export class UserService extends AbstractService<AccountEvent, AccountEventData>
}
if (parameters.newPassword !== undefined && parameters.validateNewPasswordStrength) {
if (parameters.newPassword.length < MINIMUM_PASSWORD_LENGTH) {
if (parameters.newPassword.length < this.MINIMUM_PASSWORD_LENGTH) {
return {
error: Error(Messages.InsufficientPasswordMessage(MINIMUM_PASSWORD_LENGTH)),
error: Error(Messages.InsufficientPasswordMessage(this.MINIMUM_PASSWORD_LENGTH)),
}
}
}
+10 -1
View File
@@ -6,7 +6,7 @@ export * from './Application/ApplicationStage'
export * from './Application/DeinitCallback'
export * from './Application/DeinitSource'
export * from './Application/DeinitMode'
export * from './Application/UserClientInterface'
export * from './User/UserClientInterface'
export * from './Application/WebApplicationInterface'
export * from './Backups/BackupService'
export * from './Challenge'
@@ -58,8 +58,13 @@ export * from './Item/ItemRelationshipDirection'
export * from './Mutator/MutatorClientInterface'
export * from './Payloads/PayloadManagerInterface'
export * from './Preferences/PreferenceServiceInterface'
export * from './Protection/MobileUnlockTiming'
export * from './Protection/ProtectionClientInterface'
export * from './Protection/TimingDisplayOption'
export * from './Service/AbstractService'
export * from './Service/ServiceInterface'
export * from './Session/SessionManagerResponse'
export * from './Session/SessionsClientInterface'
export * from './Status/StatusService'
export * from './Status/StatusServiceInterface'
export * from './Storage/StorageKeys'
@@ -67,6 +72,8 @@ export * from './Storage/InMemoryStore'
export * from './Storage/KeyValueStoreInterface'
export * from './Storage/StorageServiceInterface'
export * from './Storage/StorageTypes'
export * from './Strings/InfoStrings'
export * from './Strings/Messages'
export * from './Subscription/SubscriptionClientInterface'
export * from './Subscription/SubscriptionManager'
export * from './Sync/SyncMode'
@@ -74,5 +81,7 @@ export * from './Sync/SyncOptions'
export * from './Sync/SyncQueueStrategy'
export * from './Sync/SyncServiceInterface'
export * from './Sync/SyncSource'
export * from './User/UserClientInterface'
export * from './User/UserService'
export * from './Workspace/WorkspaceClientInterface'
export * from './Workspace/WorkspaceManager'
+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.147.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-03)
**Note:** Version bump only for package @standardnotes/snjs
# [2.147.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
### Features
* prioritize loading latest selected items ([#1930](https://github.com/standardnotes/app/issues/1930)) ([a6ef658](https://github.com/standardnotes/app/commit/a6ef658daef9a01f5ddacc967fe30d22f580799a))
## [2.146.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
**Note:** Version bump only for package @standardnotes/snjs
# [2.146.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-02)
### Features
* add sending user requests to process ([#1908](https://github.com/standardnotes/app/issues/1908)) ([b2faa81](https://github.com/standardnotes/app/commit/b2faa815e967a9e7052b3ce6955e967c6bc68864))
## [2.145.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-11-01)
### Bug Fixes
* **mobile:** increase font sizes and other mobile-centric improvements ([#1907](https://github.com/standardnotes/app/issues/1907)) ([994f824](https://github.com/standardnotes/app/commit/994f824757e1143a4547c975b154fd84e3ebeedf))
## [2.145.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-30)
### Bug Fixes
+35 -17
View File
@@ -8,6 +8,8 @@ import {
UserApiService,
UserApiServiceInterface,
UserRegistrationResponseBody,
UserRequestServer,
UserRequestServerInterface,
UserServer,
UserServerInterface,
WebSocketApiService,
@@ -52,6 +54,15 @@ import {
WorkspaceClientInterface,
WorkspaceManager,
ChallengePrompt,
Challenge,
ErrorAlertStrings,
SessionsClientInterface,
ProtectionsClientInterface,
UserService,
ProtocolUpgradeStrings,
CredentialsChangeFunctionResponse,
SessionStrings,
AccountEvent,
} from '@standardnotes/services'
import { FilesClientInterface } from '@standardnotes/files'
import { ComputePrivateUsername } from '@standardnotes/encryption'
@@ -68,7 +79,7 @@ import { ClientDisplayableError } from '@standardnotes/responses'
import { SnjsVersion } from './../Version'
import { SNLog } from '../Log'
import { Challenge, ChallengeResponse, ListedClientInterface } from '../Services'
import { ChallengeResponse, ListedClientInterface } from '../Services'
import { ApplicationConstructorOptions, FullyResolvedApplicationOptions } from './Options/ApplicationOptions'
import { ApplicationOptionsDefaults } from './Options/Defaults'
@@ -112,6 +123,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
private apiService!: InternalServices.SNApiService
private declare userApiService: UserApiServiceInterface
private declare userServer: UserServerInterface
private declare userRequestServer: UserRequestServerInterface
private declare subscriptionApiService: SubscriptionApiServiceInterface
private declare subscriptionServer: SubscriptionServerInterface
private declare subscriptionManager: SubscriptionClientInterface
@@ -132,7 +144,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
private keyRecoveryService!: InternalServices.SNKeyRecoveryService
private preferencesService!: InternalServices.SNPreferencesService
private featuresService!: InternalServices.SNFeaturesService
private userService!: InternalServices.UserService
private userService!: UserService
private webSocketsService!: InternalServices.SNWebSocketsService
private settingsService!: InternalServices.SNSettingsService
private mfaService!: InternalServices.SNMfaService
@@ -235,7 +247,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
return this.itemManager
}
public get protections(): InternalServices.ProtectionsClientInterface {
public get protections(): ProtectionsClientInterface {
return this.protectionService
}
@@ -255,7 +267,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
return this.mutatorService
}
public get sessions(): InternalServices.SessionsClientInterface {
public get sessions(): SessionsClientInterface {
return this.sessionManager
}
@@ -347,8 +359,8 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
await this.diskStorageService.decryptStorage()
} catch (_error) {
void this.alertService.alert(
InternalServices.ErrorAlertStrings.StorageDecryptErrorBody,
InternalServices.ErrorAlertStrings.StorageDecryptErrorTitle,
ErrorAlertStrings.StorageDecryptErrorBody,
ErrorAlertStrings.StorageDecryptErrorTitle,
)
}
}
@@ -628,12 +640,12 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
const result = await this.userService.performProtocolUpgrade()
if (result.success) {
if (this.hasAccount()) {
void this.alertService.alert(InternalServices.ProtocolUpgradeStrings.SuccessAccount)
void this.alertService.alert(ProtocolUpgradeStrings.SuccessAccount)
} else {
void this.alertService.alert(InternalServices.ProtocolUpgradeStrings.SuccessPasscodeOnly)
void this.alertService.alert(ProtocolUpgradeStrings.SuccessPasscodeOnly)
}
} else if (result.error) {
void this.alertService.alert(InternalServices.ProtocolUpgradeStrings.Fail)
void this.alertService.alert(ProtocolUpgradeStrings.Fail)
}
return result
}
@@ -848,7 +860,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
currentPassword: string,
passcode?: string,
origination = Common.KeyParamsOrigination.EmailChange,
): Promise<InternalServices.CredentialsChangeFunctionResponse> {
): Promise<CredentialsChangeFunctionResponse> {
return this.userService.changeCredentials({
currentPassword,
newEmail,
@@ -864,7 +876,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
passcode?: string,
origination = Common.KeyParamsOrigination.PasswordChange,
validateNewPasswordStrength = true,
): Promise<InternalServices.CredentialsChangeFunctionResponse> {
): Promise<CredentialsChangeFunctionResponse> {
return this.userService.changeCredentials({
currentPassword,
newPassword,
@@ -886,7 +898,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
/** Keep a reference to the soon-to-be-cleared alertService */
const alertService = this.alertService
await this.user.signOut(true)
void alertService.alert(InternalServices.SessionStrings.CurrentSessionRevoked)
void alertService.alert(SessionStrings.CurrentSessionRevoked)
}
public async validateAccountPassword(password: string): Promise<boolean> {
@@ -1064,6 +1076,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
this.createApiService()
this.createHttpService()
this.createUserServer()
this.createUserRequestServer()
this.createUserApiService()
this.createSubscriptionServer()
this.createSubscriptionApiService()
@@ -1111,6 +1124,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
;(this.apiService as unknown) = undefined
;(this.userApiService as unknown) = undefined
;(this.userServer as unknown) = undefined
;(this.userRequestServer as unknown) = undefined
;(this.subscriptionApiService as unknown) = undefined
;(this.subscriptionServer as unknown) = undefined
;(this.subscriptionManager as unknown) = undefined
@@ -1261,7 +1275,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
}
private createUserService(): void {
this.userService = new InternalServices.UserService(
this.userService = new UserService(
this.sessionManager,
this.syncService,
this.diskStorageService,
@@ -1270,17 +1284,17 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
this.alertService,
this.challengeService,
this.protectionService,
this.apiService,
this.userApiService,
this.internalEventBus,
)
this.serviceObservers.push(
this.userService.addEventObserver(async (event, data) => {
switch (event) {
case InternalServices.AccountEvent.SignedInOrRegistered: {
case AccountEvent.SignedInOrRegistered: {
void this.notifyEvent(ApplicationEvent.SignedIn)
break
}
case InternalServices.AccountEvent.SignedOut: {
case AccountEvent.SignedOut: {
await this.notifyEvent(ApplicationEvent.SignedOut)
await this.prepareForDeinit()
this.deinit(this.getDeinitMode(), data?.source || DeinitSource.SignOut)
@@ -1308,13 +1322,17 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
}
private createUserApiService() {
this.userApiService = new UserApiService(this.userServer)
this.userApiService = new UserApiService(this.userServer, this.userRequestServer)
}
private createUserServer() {
this.userServer = new UserServer(this.httpService)
}
private createUserRequestServer() {
this.userRequestServer = new UserRequestServer(this.httpService)
}
private createSubscriptionApiService() {
this.subscriptionApiService = new SubscriptionApiService(this.subscriptionServer)
}
@@ -1,5 +1,5 @@
import { InfoStrings } from '../Strings/Info'
import { NoteType } from '@standardnotes/features'
import { InfoStrings } from '@standardnotes/services'
import {
NoteMutator,
SNNote,
@@ -5,4 +5,6 @@ export enum ReactNativeToWebEvent {
LosingFocus = 'LosingFocus',
AndroidBackButtonPressed = 'AndroidBackButtonPressed',
ColorSchemeChanged = 'ColorSchemeChanged',
KeyboardFrameWillChange = 'KeyboardFrameWillChange',
KeyboardFrameDidChange = 'KeyboardFrameDidChange',
}
+3 -2
View File
@@ -1,8 +1,6 @@
import { AnyKeyParamsContent } from '@standardnotes/common'
import { SNLog } from '@Lib/Log'
import { EncryptedPayload, EncryptedTransferPayload, isErrorDecryptingPayload } from '@standardnotes/models'
import { Challenge } from '../Services/Challenge'
import { KeychainRecoveryStrings, SessionStrings } from '../Services/Api/Messages'
import { PreviousSnjsVersion1_0_0, PreviousSnjsVersion2_0_0, SnjsVersion } from '../Version'
import { Migration } from '@Lib/Migrations/Migration'
import {
@@ -12,6 +10,9 @@ import {
ChallengeValidation,
ChallengeReason,
ChallengePrompt,
KeychainRecoveryStrings,
SessionStrings,
Challenge,
} from '@standardnotes/services'
import { isNullOrUndefined } from '@standardnotes/utils'
import { CreateReader } from './StorageReaders/Functions'
+7 -2
View File
@@ -1,6 +1,11 @@
import { Challenge } from '../Services/Challenge'
import { MigrationServices } from './MigrationServices'
import { ApplicationStage, ChallengeValidation, ChallengeReason, ChallengePrompt } from '@standardnotes/services'
import {
ApplicationStage,
ChallengeValidation,
ChallengeReason,
ChallengePrompt,
Challenge,
} from '@standardnotes/services'
type StageHandler = () => Promise<void>
@@ -1,5 +1,5 @@
import { SNRootKey } from '@standardnotes/encryption'
import { Challenge, ChallengeService } from '../Challenge'
import { ChallengeService } from '../Challenge'
import { ListedService } from '../Listed/ListedService'
import { ActionResponse, HttpResponse } from '@standardnotes/responses'
import { ContentType } from '@standardnotes/common'
@@ -31,6 +31,7 @@ import {
ChallengeReason,
ChallengePrompt,
EncryptionService,
Challenge,
} from '@standardnotes/services'
/**
+49 -48
View File
@@ -13,28 +13,44 @@ import {
MetaReceivedData,
DiagnosticInfo,
KeyValueStoreInterface,
API_MESSAGE_GENERIC_SYNC_FAIL,
API_MESSAGE_GENERIC_TOKEN_REFRESH_FAIL,
API_MESSAGE_CHANGE_CREDENTIALS_IN_PROGRESS,
API_MESSAGE_FAILED_ACCESS_PURCHASE,
API_MESSAGE_FAILED_CREATE_FILE_TOKEN,
API_MESSAGE_FAILED_DELETE_REVISION,
API_MESSAGE_FAILED_GET_SETTINGS,
API_MESSAGE_FAILED_LISTED_REGISTRATION,
API_MESSAGE_FAILED_OFFLINE_ACTIVATION,
API_MESSAGE_FAILED_OFFLINE_FEATURES,
API_MESSAGE_FAILED_SUBSCRIPTION_INFO,
API_MESSAGE_FAILED_UPDATE_SETTINGS,
API_MESSAGE_GENERIC_CHANGE_CREDENTIALS_FAIL,
API_MESSAGE_GENERIC_INTEGRITY_CHECK_FAIL,
API_MESSAGE_GENERIC_INVALID_LOGIN,
API_MESSAGE_GENERIC_SINGLE_ITEM_SYNC_FAIL,
API_MESSAGE_INVALID_SESSION,
API_MESSAGE_LOGIN_IN_PROGRESS,
API_MESSAGE_TOKEN_REFRESH_IN_PROGRESS,
} from '@standardnotes/services'
import { FilesApiInterface } from '@standardnotes/files'
import { ServerSyncPushContextualPayload, SNFeatureRepo, FileContent } from '@standardnotes/models'
import * as Responses from '@standardnotes/responses'
import { API_MESSAGE_FAILED_OFFLINE_ACTIVATION } from '@Lib/Services/Api/Messages'
import { HttpParams, HttpRequest, HttpVerb, SNHttpService } from './HttpService'
import { isUrlFirstParty, TRUSTED_FEATURE_HOSTS } from '@Lib/Hosts'
import { Paths } from './Paths'
import { Session } from '../Session/Sessions/Session'
import { TokenSession } from '../Session/Sessions/TokenSession'
import { DiskStorageService } from '../Storage/DiskStorageService'
import { UserServerInterface } from '../User/UserServerInterface'
import { HttpResponseMeta } from '@standardnotes/api'
import { UuidString } from '../../Types/UuidString'
import * as messages from '@Lib/Services/Api/Messages'
import merge from 'lodash/merge'
import { SettingsServerInterface } from '../Settings/SettingsServerInterface'
import { Strings } from '@Lib/Strings'
import { SNRootKeyParams } from '@standardnotes/encryption'
import { ApiEndpointParam, ClientDisplayableError, CreateValetTokenPayload } from '@standardnotes/responses'
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
import { HttpResponseMeta } from '@standardnotes/api'
/** Legacy api version field to be specified in params when calling v0 APIs. */
const V0_API_VERSION = '20200115'
@@ -48,7 +64,6 @@ export class SNApiService
FilesApiInterface,
IntegrityApiInterface,
ItemsServerInterface,
UserServerInterface,
SettingsServerInterface
{
private session?: Session
@@ -232,7 +247,7 @@ export class SNApiService
return this.request({
verb: HttpVerb.Post,
url: joinPaths(this.host, Paths.v2.keyParams),
fallbackErrorMessage: messages.API_MESSAGE_GENERIC_INVALID_LOGIN,
fallbackErrorMessage: API_MESSAGE_GENERIC_INVALID_LOGIN,
params,
/** A session is optional here, if valid, endpoint bypasses 2FA and returns additional params */
authentication: this.session?.authorizationValue,
@@ -245,7 +260,7 @@ export class SNApiService
ephemeral: boolean
}): Promise<Responses.SignInResponse | Responses.HttpResponse> {
if (this.authenticating) {
return this.createErrorResponse(messages.API_MESSAGE_LOGIN_IN_PROGRESS) as Responses.SignInResponse
return this.createErrorResponse(API_MESSAGE_LOGIN_IN_PROGRESS) as Responses.SignInResponse
}
this.authenticating = true
const url = joinPaths(this.host, Paths.v2.signIn)
@@ -260,7 +275,7 @@ export class SNApiService
verb: HttpVerb.Post,
url,
params,
fallbackErrorMessage: messages.API_MESSAGE_GENERIC_INVALID_LOGIN,
fallbackErrorMessage: API_MESSAGE_GENERIC_INVALID_LOGIN,
})
this.authenticating = false
@@ -285,7 +300,7 @@ export class SNApiService
newEmail?: string
}): Promise<Responses.ChangeCredentialsResponse | Responses.HttpResponse> {
if (this.changing) {
return this.createErrorResponse(messages.API_MESSAGE_CHANGE_CREDENTIALS_IN_PROGRESS)
return this.createErrorResponse(API_MESSAGE_CHANGE_CREDENTIALS_IN_PROGRESS)
}
const preprocessingError = this.preprocessingError()
if (preprocessingError) {
@@ -309,10 +324,7 @@ export class SNApiService
params,
})
}
return this.errorResponseWithFallbackMessage(
errorResponse,
messages.API_MESSAGE_GENERIC_CHANGE_CREDENTIALS_FAIL,
)
return this.errorResponseWithFallbackMessage(errorResponse, API_MESSAGE_GENERIC_CHANGE_CREDENTIALS_FAIL)
})
this.processResponse(response)
@@ -321,17 +333,6 @@ export class SNApiService
return response
}
public async deleteAccount(userUuid: string): Promise<Responses.HttpResponse | Responses.MinimalHttpResponse> {
const url = joinPaths(this.host, Paths.v1.deleteAccount(userUuid))
const response = await this.request({
verb: HttpVerb.Delete,
url,
authentication: this.session?.authorizationValue,
fallbackErrorMessage: messages.ServerErrorStrings.DeleteAccountError,
})
return response
}
async sync(
payloads: ServerSyncPushContextualPayload[],
lastSyncToken: string,
@@ -360,7 +361,7 @@ export class SNApiService
params,
})
}
return this.errorResponseWithFallbackMessage(errorResponse, messages.API_MESSAGE_GENERIC_SYNC_FAIL)
return this.errorResponseWithFallbackMessage(errorResponse, API_MESSAGE_GENERIC_SYNC_FAIL)
})
this.processResponse(response)
@@ -405,7 +406,7 @@ export class SNApiService
})
.catch((errorResponse) => {
this.preprocessAuthenticatedErrorResponse(errorResponse)
return this.errorResponseWithFallbackMessage(errorResponse, messages.API_MESSAGE_GENERIC_TOKEN_REFRESH_FAIL)
return this.errorResponseWithFallbackMessage(errorResponse, API_MESSAGE_GENERIC_TOKEN_REFRESH_FAIL)
})
this.refreshingSession = false
return result
@@ -427,7 +428,7 @@ export class SNApiService
url,
})
}
return this.errorResponseWithFallbackMessage(errorResponse, messages.API_MESSAGE_GENERIC_SYNC_FAIL)
return this.errorResponseWithFallbackMessage(errorResponse, API_MESSAGE_GENERIC_SYNC_FAIL)
})
this.processResponse(response)
@@ -451,7 +452,7 @@ export class SNApiService
url,
})
}
return this.errorResponseWithFallbackMessage(errorResponse, messages.API_MESSAGE_GENERIC_SYNC_FAIL)
return this.errorResponseWithFallbackMessage(errorResponse, API_MESSAGE_GENERIC_SYNC_FAIL)
})
this.processResponse(response)
return response
@@ -473,7 +474,7 @@ export class SNApiService
url,
})
}
return this.errorResponseWithFallbackMessage(errorResponse, messages.API_MESSAGE_GENERIC_SYNC_FAIL)
return this.errorResponseWithFallbackMessage(errorResponse, API_MESSAGE_GENERIC_SYNC_FAIL)
})
this.processResponse(response)
return response
@@ -498,7 +499,7 @@ export class SNApiService
url,
})
}
return this.errorResponseWithFallbackMessage(errorResponse, messages.API_MESSAGE_GENERIC_SYNC_FAIL)
return this.errorResponseWithFallbackMessage(errorResponse, API_MESSAGE_GENERIC_SYNC_FAIL)
})
this.processResponse(response)
return response
@@ -516,7 +517,7 @@ export class SNApiService
url,
})
}
return this.errorResponseWithFallbackMessage(errorResponse, messages.API_MESSAGE_GENERIC_SYNC_FAIL)
return this.errorResponseWithFallbackMessage(errorResponse, API_MESSAGE_GENERIC_SYNC_FAIL)
})
this.processResponse(response)
return response
@@ -546,7 +547,7 @@ export class SNApiService
return await this.tokenRefreshableRequest<Responses.ListSettingsResponse>({
verb: HttpVerb.Get,
url: joinPaths(this.host, Paths.v1.settings(userUuid)),
fallbackErrorMessage: messages.API_MESSAGE_FAILED_GET_SETTINGS,
fallbackErrorMessage: API_MESSAGE_FAILED_GET_SETTINGS,
authentication: this.session?.authorizationValue,
})
}
@@ -566,7 +567,7 @@ export class SNApiService
verb: HttpVerb.Put,
url: joinPaths(this.host, Paths.v1.settings(userUuid)),
authentication: this.session?.authorizationValue,
fallbackErrorMessage: messages.API_MESSAGE_FAILED_UPDATE_SETTINGS,
fallbackErrorMessage: API_MESSAGE_FAILED_UPDATE_SETTINGS,
params,
})
}
@@ -576,7 +577,7 @@ export class SNApiService
verb: HttpVerb.Get,
url: joinPaths(this.host, Paths.v1.setting(userUuid, settingName.toLowerCase() as SettingName)),
authentication: this.session?.authorizationValue,
fallbackErrorMessage: messages.API_MESSAGE_FAILED_GET_SETTINGS,
fallbackErrorMessage: API_MESSAGE_FAILED_GET_SETTINGS,
})
}
@@ -591,7 +592,7 @@ export class SNApiService
Paths.v1.subscriptionSetting(userUuid, settingName.toLowerCase() as SubscriptionSettingName),
),
authentication: this.session?.authorizationValue,
fallbackErrorMessage: messages.API_MESSAGE_FAILED_GET_SETTINGS,
fallbackErrorMessage: API_MESSAGE_FAILED_GET_SETTINGS,
})
}
@@ -600,7 +601,7 @@ export class SNApiService
verb: HttpVerb.Delete,
url: joinPaths(this.host, Paths.v1.setting(userUuid, settingName)),
authentication: this.session?.authorizationValue,
fallbackErrorMessage: messages.API_MESSAGE_FAILED_UPDATE_SETTINGS,
fallbackErrorMessage: API_MESSAGE_FAILED_UPDATE_SETTINGS,
})
}
@@ -612,7 +613,7 @@ export class SNApiService
const response = await this.tokenRefreshableRequest({
verb: HttpVerb.Delete,
url,
fallbackErrorMessage: messages.API_MESSAGE_FAILED_DELETE_REVISION,
fallbackErrorMessage: API_MESSAGE_FAILED_DELETE_REVISION,
authentication: this.session?.authorizationValue,
})
return response
@@ -623,7 +624,7 @@ export class SNApiService
verb: HttpVerb.Get,
url,
external: true,
fallbackErrorMessage: messages.API_MESSAGE_GENERIC_INVALID_LOGIN,
fallbackErrorMessage: API_MESSAGE_GENERIC_INVALID_LOGIN,
})
}
@@ -633,7 +634,7 @@ export class SNApiService
verb: HttpVerb.Get,
url,
authentication: this.session?.authorizationValue,
fallbackErrorMessage: messages.API_MESSAGE_FAILED_SUBSCRIPTION_INFO,
fallbackErrorMessage: API_MESSAGE_FAILED_SUBSCRIPTION_INFO,
})
return response
}
@@ -645,7 +646,7 @@ export class SNApiService
const response = await this.request({
verb: HttpVerb.Get,
url,
fallbackErrorMessage: messages.API_MESSAGE_FAILED_SUBSCRIPTION_INFO,
fallbackErrorMessage: API_MESSAGE_FAILED_SUBSCRIPTION_INFO,
})
return response
}
@@ -656,7 +657,7 @@ export class SNApiService
verb: HttpVerb.Post,
url,
authentication: this.session?.authorizationValue,
fallbackErrorMessage: messages.API_MESSAGE_FAILED_ACCESS_PURCHASE,
fallbackErrorMessage: API_MESSAGE_FAILED_ACCESS_PURCHASE,
})
return (response as Responses.PostSubscriptionTokensResponse).data?.token
}
@@ -680,7 +681,7 @@ export class SNApiService
const response: Responses.HttpResponse | Responses.GetOfflineFeaturesResponse = await this.request({
verb: HttpVerb.Get,
url: featuresUrl,
fallbackErrorMessage: messages.API_MESSAGE_FAILED_OFFLINE_FEATURES,
fallbackErrorMessage: API_MESSAGE_FAILED_OFFLINE_FEATURES,
customHeaders: [{ key: 'x-offline-token', value: extensionKey }],
})
@@ -702,7 +703,7 @@ export class SNApiService
return await this.tokenRefreshableRequest<Responses.ListedRegistrationResponse>({
verb: HttpVerb.Post,
url: joinPaths(this.host, Paths.v1.listedRegistration(this.user.uuid)),
fallbackErrorMessage: messages.API_MESSAGE_FAILED_LISTED_REGISTRATION,
fallbackErrorMessage: API_MESSAGE_FAILED_LISTED_REGISTRATION,
authentication: this.session?.authorizationValue,
})
}
@@ -723,7 +724,7 @@ export class SNApiService
verb: HttpVerb.Post,
url: url,
authentication: this.session?.authorizationValue,
fallbackErrorMessage: messages.API_MESSAGE_FAILED_CREATE_FILE_TOKEN,
fallbackErrorMessage: API_MESSAGE_FAILED_CREATE_FILE_TOKEN,
params,
})
@@ -856,7 +857,7 @@ export class SNApiService
params: {
integrityPayloads,
},
fallbackErrorMessage: messages.API_MESSAGE_GENERIC_INTEGRITY_CHECK_FAIL,
fallbackErrorMessage: API_MESSAGE_GENERIC_INTEGRITY_CHECK_FAIL,
authentication: this.session?.authorizationValue,
})
}
@@ -865,17 +866,17 @@ export class SNApiService
return await this.tokenRefreshableRequest<Responses.GetSingleItemResponse>({
verb: HttpVerb.Get,
url: joinPaths(this.host, Paths.v1.getSingleItem(itemUuid)),
fallbackErrorMessage: messages.API_MESSAGE_GENERIC_SINGLE_ITEM_SYNC_FAIL,
fallbackErrorMessage: API_MESSAGE_GENERIC_SINGLE_ITEM_SYNC_FAIL,
authentication: this.session?.authorizationValue,
})
}
private preprocessingError() {
if (this.refreshingSession) {
return this.createErrorResponse(messages.API_MESSAGE_TOKEN_REFRESH_IN_PROGRESS)
return this.createErrorResponse(API_MESSAGE_TOKEN_REFRESH_IN_PROGRESS)
}
if (!this.session) {
return this.createErrorResponse(messages.API_MESSAGE_INVALID_SESSION)
return this.createErrorResponse(API_MESSAGE_INVALID_SESSION)
}
return undefined
}

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