feat: add subscription manager to handle subscription sharing (#1517)
* feat: add subscription manager to handle subscription sharing * fix(services): add missing methods to the interface * fix(services): add subscription manager specs * feat(snjs): add subscriptions e2e tests * fix(snjs): add wait in subscription cancelling test * fix(snjs): checking for canceled invitations in tests * fix(snjs): add e2e test for restored limit of subscription invitations * chore(lint): fix linter issues
This commit is contained in:
BIN
.yarn/cache/@eslint-eslintrc-npm-1.3.2-fd8de37609-2074dca47d.zip
vendored
Normal file
BIN
.yarn/cache/@eslint-eslintrc-npm-1.3.2-fd8de37609-2074dca47d.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/eslint-npm-8.23.1-bc9a4812f6-a727e15492.zip
vendored
Normal file
BIN
.yarn/cache/eslint-npm-8.23.1-bc9a4812f6-a727e15492.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/js-sdsl-npm-4.1.4-334fa1c399-1977cea4ab.zip
vendored
Normal file
BIN
.yarn/cache/js-sdsl-npm-4.1.4-334fa1c399-1977cea4ab.zip
vendored
Normal file
Binary file not shown.
@@ -29,6 +29,7 @@
|
|||||||
"build:mobile": "yarn workspaces foreach -pt --verbose -R --from @standardnotes/mobile --exclude @standardnotes/components-meta run build",
|
"build:mobile": "yarn workspaces foreach -pt --verbose -R --from @standardnotes/mobile --exclude @standardnotes/components-meta run build",
|
||||||
"build:snjs": "yarn workspaces foreach -pt --verbose -R --from @standardnotes/snjs --exclude @standardnotes/components-meta run build",
|
"build:snjs": "yarn workspaces foreach -pt --verbose -R --from @standardnotes/snjs --exclude @standardnotes/components-meta run build",
|
||||||
"build:services": "yarn workspaces foreach -pt --verbose -R --from @standardnotes/services --exclude @standardnotes/components-meta run build",
|
"build:services": "yarn workspaces foreach -pt --verbose -R --from @standardnotes/services --exclude @standardnotes/components-meta run build",
|
||||||
|
"build:api": "yarn workspaces foreach -pt --verbose -R --from @standardnotes/api --exclude @standardnotes/components-meta run build",
|
||||||
"start:server:web": "lerna run start --scope=@standardnotes/web",
|
"start:server:web": "lerna run start --scope=@standardnotes/web",
|
||||||
"start:server:e2e": "lerna run start:test-server --scope=@standardnotes/snjs",
|
"start:server:e2e": "lerna run start:test-server --scope=@standardnotes/snjs",
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
|
|||||||
@@ -35,12 +35,11 @@
|
|||||||
"ts-jest": "^28.0.5"
|
"ts-jest": "^28.0.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standardnotes/common": "^1.23.1",
|
"@standardnotes/common": "^1.32.0",
|
||||||
"@standardnotes/encryption": "workspace:*",
|
"@standardnotes/encryption": "workspace:*",
|
||||||
"@standardnotes/models": "workspace:*",
|
"@standardnotes/models": "workspace:*",
|
||||||
"@standardnotes/responses": "workspace:*",
|
"@standardnotes/responses": "workspace:*",
|
||||||
"@standardnotes/security": "^1.1.0",
|
"@standardnotes/security": "^1.1.0",
|
||||||
"@standardnotes/services": "workspace:*",
|
|
||||||
"@standardnotes/utils": "workspace:*",
|
"@standardnotes/utils": "workspace:*",
|
||||||
"reflect-metadata": "^0.1.13"
|
"reflect-metadata": "^0.1.13"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Environment } from '@standardnotes/services'
|
import { Environment } from '@standardnotes/models'
|
||||||
|
|
||||||
import { HttpResponseMeta } from './HttpResponseMeta'
|
import { HttpResponseMeta } from './HttpResponseMeta'
|
||||||
import { HttpService } from './HttpService'
|
import { HttpService } from './HttpService'
|
||||||
|
|
||||||
@@ -24,4 +25,14 @@ describe('HttpService', () => {
|
|||||||
|
|
||||||
expect(service['host']).toEqual('http://foo')
|
expect(service['host']).toEqual('http://foo')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should set and use the authorization token', () => {
|
||||||
|
const service = createService()
|
||||||
|
|
||||||
|
expect(service['authorizationToken']).toBeUndefined()
|
||||||
|
|
||||||
|
service.setAuthorizationToken('foo-bar')
|
||||||
|
|
||||||
|
expect(service['authorizationToken']).toEqual('foo-bar')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { isString, joinPaths } from '@standardnotes/utils'
|
import { isString, joinPaths } from '@standardnotes/utils'
|
||||||
import { Environment } from '@standardnotes/services'
|
import { Environment } from '@standardnotes/models'
|
||||||
import { HttpRequestParams } from './HttpRequestParams'
|
import { HttpRequestParams } from './HttpRequestParams'
|
||||||
import { HttpVerb } from './HttpVerb'
|
import { HttpVerb } from './HttpVerb'
|
||||||
import { HttpRequest } from './HttpRequest'
|
import { HttpRequest } from './HttpRequest'
|
||||||
@@ -12,6 +12,8 @@ import { HttpResponseMeta } from './HttpResponseMeta'
|
|||||||
import { HttpErrorResponseBody } from './HttpErrorResponseBody'
|
import { HttpErrorResponseBody } from './HttpErrorResponseBody'
|
||||||
|
|
||||||
export class HttpService implements HttpServiceInterface {
|
export class HttpService implements HttpServiceInterface {
|
||||||
|
private authorizationToken?: string
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private environment: Environment,
|
private environment: Environment,
|
||||||
private appVersion: string,
|
private appVersion: string,
|
||||||
@@ -20,28 +22,57 @@ export class HttpService implements HttpServiceInterface {
|
|||||||
private updateMetaCallback: (meta: HttpResponseMeta) => void,
|
private updateMetaCallback: (meta: HttpResponseMeta) => void,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
setAuthorizationToken(authorizationToken: string): void {
|
||||||
|
this.authorizationToken = authorizationToken
|
||||||
|
}
|
||||||
|
|
||||||
setHost(host: string): void {
|
setHost(host: string): void {
|
||||||
this.host = host
|
this.host = host
|
||||||
}
|
}
|
||||||
|
|
||||||
async get(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse> {
|
async get(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse> {
|
||||||
return this.runHttp({ url: joinPaths(this.host, path), params, verb: HttpVerb.Get, authentication })
|
return this.runHttp({
|
||||||
|
url: joinPaths(this.host, path),
|
||||||
|
params,
|
||||||
|
verb: HttpVerb.Get,
|
||||||
|
authentication: authentication ?? this.authorizationToken,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async post(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse> {
|
async post(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse> {
|
||||||
return this.runHttp({ url: joinPaths(this.host, path), params, verb: HttpVerb.Post, authentication })
|
return this.runHttp({
|
||||||
|
url: joinPaths(this.host, path),
|
||||||
|
params,
|
||||||
|
verb: HttpVerb.Post,
|
||||||
|
authentication: authentication ?? this.authorizationToken,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async put(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse> {
|
async put(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse> {
|
||||||
return this.runHttp({ url: joinPaths(this.host, path), params, verb: HttpVerb.Put, authentication })
|
return this.runHttp({
|
||||||
|
url: joinPaths(this.host, path),
|
||||||
|
params,
|
||||||
|
verb: HttpVerb.Put,
|
||||||
|
authentication: authentication ?? this.authorizationToken,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async patch(path: string, params: HttpRequestParams, authentication?: string): Promise<HttpResponse> {
|
async patch(path: string, params: HttpRequestParams, authentication?: string): Promise<HttpResponse> {
|
||||||
return this.runHttp({ url: joinPaths(this.host, path), params, verb: HttpVerb.Patch, authentication })
|
return this.runHttp({
|
||||||
|
url: joinPaths(this.host, path),
|
||||||
|
params,
|
||||||
|
verb: HttpVerb.Patch,
|
||||||
|
authentication: authentication ?? this.authorizationToken,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse> {
|
async delete(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse> {
|
||||||
return this.runHttp({ url: joinPaths(this.host, path), params, verb: HttpVerb.Delete, authentication })
|
return this.runHttp({
|
||||||
|
url: joinPaths(this.host, path),
|
||||||
|
params,
|
||||||
|
verb: HttpVerb.Delete,
|
||||||
|
authentication: authentication ?? this.authorizationToken,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private async runHttp(httpRequest: HttpRequest): Promise<HttpResponse> {
|
private async runHttp(httpRequest: HttpRequest): Promise<HttpResponse> {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { HttpResponse } from './HttpResponse'
|
|||||||
|
|
||||||
export interface HttpServiceInterface {
|
export interface HttpServiceInterface {
|
||||||
setHost(host: string): void
|
setHost(host: string): void
|
||||||
|
setAuthorizationToken(authorizationToken: string): void
|
||||||
get(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse>
|
get(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse>
|
||||||
post(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse>
|
post(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse>
|
||||||
put(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse>
|
put(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse>
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
import { Either } from '@standardnotes/common'
|
||||||
|
|
||||||
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
import { HttpResponse } from '../../Http/HttpResponse'
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
import { SubscriptionInviteAcceptResponseBody } from './SubscriptionInviteAcceptResponseBody'
|
import { SubscriptionInviteAcceptResponseBody } from './SubscriptionInviteAcceptResponseBody'
|
||||||
|
|
||||||
export interface SubscriptionInviteAcceptResponse extends HttpResponse {
|
export interface SubscriptionInviteAcceptResponse extends HttpResponse {
|
||||||
data: SubscriptionInviteAcceptResponseBody | HttpErrorResponseBody
|
data: Either<SubscriptionInviteAcceptResponseBody, HttpErrorResponseBody>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
import { Either } from '@standardnotes/common'
|
||||||
|
|
||||||
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
import { HttpResponse } from '../../Http/HttpResponse'
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
import { SubscriptionInviteCancelResponseBody } from './SubscriptionInviteCancelResponseBody'
|
import { SubscriptionInviteCancelResponseBody } from './SubscriptionInviteCancelResponseBody'
|
||||||
|
|
||||||
export interface SubscriptionInviteCancelResponse extends HttpResponse {
|
export interface SubscriptionInviteCancelResponse extends HttpResponse {
|
||||||
data: SubscriptionInviteCancelResponseBody | HttpErrorResponseBody
|
data: Either<SubscriptionInviteCancelResponseBody, HttpErrorResponseBody>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
import { Either } from '@standardnotes/common'
|
||||||
|
|
||||||
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
import { HttpResponse } from '../../Http/HttpResponse'
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
import { SubscriptionInviteDeclineResponseBody } from './SubscriptionInviteDeclineResponseBody'
|
import { SubscriptionInviteDeclineResponseBody } from './SubscriptionInviteDeclineResponseBody'
|
||||||
|
|
||||||
export interface SubscriptionInviteDeclineResponse extends HttpResponse {
|
export interface SubscriptionInviteDeclineResponse extends HttpResponse {
|
||||||
data: SubscriptionInviteDeclineResponseBody | HttpErrorResponseBody
|
data: Either<SubscriptionInviteDeclineResponseBody, HttpErrorResponseBody>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
import { Either } from '@standardnotes/common'
|
||||||
|
|
||||||
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
import { HttpResponse } from '../../Http/HttpResponse'
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
import { SubscriptionInviteListResponseBody } from './SubscriptionInviteListResponseBody'
|
import { SubscriptionInviteListResponseBody } from './SubscriptionInviteListResponseBody'
|
||||||
|
|
||||||
export interface SubscriptionInviteListResponse extends HttpResponse {
|
export interface SubscriptionInviteListResponse extends HttpResponse {
|
||||||
data: SubscriptionInviteListResponseBody | HttpErrorResponseBody
|
data: Either<SubscriptionInviteListResponseBody, HttpErrorResponseBody>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
import { Either } from '@standardnotes/common'
|
||||||
|
|
||||||
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
import { HttpResponse } from '../../Http/HttpResponse'
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
import { SubscriptionInviteResponseBody } from './SubscriptionInviteResponseBody'
|
import { SubscriptionInviteResponseBody } from './SubscriptionInviteResponseBody'
|
||||||
|
|
||||||
export interface SubscriptionInviteResponse extends HttpResponse {
|
export interface SubscriptionInviteResponse extends HttpResponse {
|
||||||
data: SubscriptionInviteResponseBody | HttpErrorResponseBody
|
data: Either<SubscriptionInviteResponseBody, HttpErrorResponseBody>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from './User/Paths'
|
export * from './Subscription/SubscriptionServer'
|
||||||
|
export * from './Subscription/SubscriptionServerInterface'
|
||||||
export * from './User/UserServer'
|
export * from './User/UserServer'
|
||||||
export * from './User/UserServerInterface'
|
export * from './User/UserServerInterface'
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
"typescript": "*"
|
"typescript": "*"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standardnotes/common": "^1.23.1",
|
"@standardnotes/common": "^1.32.0",
|
||||||
"@standardnotes/models": "workspace:*",
|
"@standardnotes/models": "workspace:*",
|
||||||
"@standardnotes/responses": "workspace:*",
|
"@standardnotes/responses": "workspace:*",
|
||||||
"@standardnotes/sncrypto-common": "workspace:*",
|
"@standardnotes/sncrypto-common": "workspace:*",
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standardnotes/auth": "^3.19.4",
|
"@standardnotes/auth": "^3.19.4",
|
||||||
"@standardnotes/common": "^1.23.1",
|
"@standardnotes/common": "^1.32.0",
|
||||||
"@standardnotes/security": "^1.2.0",
|
"@standardnotes/security": "^1.2.0",
|
||||||
"reflect-metadata": "^0.1.13"
|
"reflect-metadata": "^0.1.13"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
"ts-node": "^10.5.0"
|
"ts-node": "^10.5.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standardnotes/common": "^1.23.1",
|
"@standardnotes/common": "^1.32.0",
|
||||||
"@standardnotes/files": "workspace:*",
|
"@standardnotes/files": "workspace:*",
|
||||||
"@standardnotes/utils": "workspace:*",
|
"@standardnotes/utils": "workspace:*",
|
||||||
"@types/wicg-file-system-access": "^2020.9.5",
|
"@types/wicg-file-system-access": "^2020.9.5",
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
"ts-jest": "^28.0.5"
|
"ts-jest": "^28.0.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standardnotes/common": "^1.23.1",
|
"@standardnotes/common": "^1.32.0",
|
||||||
"@standardnotes/encryption": "workspace:*",
|
"@standardnotes/encryption": "workspace:*",
|
||||||
"@standardnotes/models": "workspace:*",
|
"@standardnotes/models": "workspace:*",
|
||||||
"@standardnotes/responses": "workspace:*",
|
"@standardnotes/responses": "workspace:*",
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
"typescript": "*"
|
"typescript": "*"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standardnotes/common": "^1.23.1",
|
"@standardnotes/common": "^1.32.0",
|
||||||
"@standardnotes/features": "workspace:*",
|
"@standardnotes/features": "workspace:*",
|
||||||
"@standardnotes/responses": "workspace:*",
|
"@standardnotes/responses": "workspace:*",
|
||||||
"@standardnotes/utils": "workspace:*",
|
"@standardnotes/utils": "workspace:*",
|
||||||
|
|||||||
6
packages/models/src/Domain/Device/Environment.ts
Normal file
6
packages/models/src/Domain/Device/Environment.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export enum Environment {
|
||||||
|
Web = 1,
|
||||||
|
Desktop = 2,
|
||||||
|
Mobile = 3,
|
||||||
|
NativeMobileWeb = 4,
|
||||||
|
}
|
||||||
@@ -1,10 +1,3 @@
|
|||||||
export enum Environment {
|
|
||||||
Web = 1,
|
|
||||||
Desktop = 2,
|
|
||||||
Mobile = 3,
|
|
||||||
NativeMobileWeb = 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum Platform {
|
export enum Platform {
|
||||||
Ios = 1,
|
Ios = 1,
|
||||||
Android = 2,
|
Android = 2,
|
||||||
@@ -28,6 +28,8 @@ export * from './Api/Subscription/Invitation'
|
|||||||
export * from './Api/Subscription/InvitationStatus'
|
export * from './Api/Subscription/InvitationStatus'
|
||||||
export * from './Api/Subscription/InviteeIdentifierType'
|
export * from './Api/Subscription/InviteeIdentifierType'
|
||||||
export * from './Api/Subscription/InviterIdentifierType'
|
export * from './Api/Subscription/InviterIdentifierType'
|
||||||
|
export * from './Device/Environment'
|
||||||
|
export * from './Device/Platform'
|
||||||
export * from './Local/KeyParams/RootKeyParamsInterface'
|
export * from './Local/KeyParams/RootKeyParamsInterface'
|
||||||
export * from './Local/RootKey/KeychainTypes'
|
export * from './Local/RootKey/KeychainTypes'
|
||||||
export * from './Local/RootKey/RootKeyContent'
|
export * from './Local/RootKey/RootKeyContent'
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
"ts-jest": "^28.0.5"
|
"ts-jest": "^28.0.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standardnotes/common": "^1.23.1",
|
"@standardnotes/common": "^1.32.0",
|
||||||
"@standardnotes/features": "workspace:*",
|
"@standardnotes/features": "workspace:*",
|
||||||
"@standardnotes/security": "^1.1.0",
|
"@standardnotes/security": "^1.1.0",
|
||||||
"reflect-metadata": "^0.1.13"
|
"reflect-metadata": "^0.1.13"
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ module.exports = {
|
|||||||
coverageThreshold: {
|
coverageThreshold: {
|
||||||
global: {
|
global: {
|
||||||
branches: 9,
|
branches: 9,
|
||||||
functions: 9,
|
functions: 10,
|
||||||
lines: 16,
|
lines: 17,
|
||||||
statements: 16
|
statements: 16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,13 @@
|
|||||||
"prebuild": "yarn clean",
|
"prebuild": "yarn clean",
|
||||||
"build": "tsc -p tsconfig.json",
|
"build": "tsc -p tsconfig.json",
|
||||||
"lint": "eslint . --ext .ts",
|
"lint": "eslint . --ext .ts",
|
||||||
|
"lint:fix": "eslint . --ext .ts --fix",
|
||||||
"test": "jest spec --coverage"
|
"test": "jest spec --coverage"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@standardnotes/api": "workspace:^",
|
||||||
"@standardnotes/auth": "^3.19.4",
|
"@standardnotes/auth": "^3.19.4",
|
||||||
"@standardnotes/common": "^1.30.0",
|
"@standardnotes/common": "^1.32.0",
|
||||||
"@standardnotes/encryption": "workspace:^",
|
"@standardnotes/encryption": "workspace:^",
|
||||||
"@standardnotes/files": "workspace:^",
|
"@standardnotes/files": "workspace:^",
|
||||||
"@standardnotes/models": "workspace:^",
|
"@standardnotes/models": "workspace:^",
|
||||||
@@ -37,6 +39,7 @@
|
|||||||
"@types/jest": "^28.1.5",
|
"@types/jest": "^28.1.5",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.30.0",
|
"@typescript-eslint/eslint-plugin": "^5.30.0",
|
||||||
"@typescript-eslint/parser": "^5.12.1",
|
"@typescript-eslint/parser": "^5.12.1",
|
||||||
|
"eslint": "^8.23.1",
|
||||||
"eslint-plugin-prettier": "*",
|
"eslint-plugin-prettier": "*",
|
||||||
"jest": "^28.1.2",
|
"jest": "^28.1.2",
|
||||||
"ts-jest": "^28.0.5"
|
"ts-jest": "^28.0.5"
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { ApplicationIdentifier, ContentType } from '@standardnotes/common'
|
import { ApplicationIdentifier, ContentType } from '@standardnotes/common'
|
||||||
import { BackupFile, DecryptedItemInterface, ItemStream, PrefKey, PrefValue } from '@standardnotes/models'
|
import { BackupFile, DecryptedItemInterface, ItemStream, Platform, PrefKey, PrefValue } from '@standardnotes/models'
|
||||||
import { FilesClientInterface } from '@standardnotes/files'
|
import { FilesClientInterface } from '@standardnotes/files'
|
||||||
import { AlertService } from '../Alert/AlertService'
|
import { AlertService } from '../Alert/AlertService'
|
||||||
|
|
||||||
import { ComponentManagerInterface } from '../Component/ComponentManagerInterface'
|
import { ComponentManagerInterface } from '../Component/ComponentManagerInterface'
|
||||||
import { Platform } from '../Device/Environments'
|
|
||||||
import { ApplicationEvent } from '../Event/ApplicationEvent'
|
import { ApplicationEvent } from '../Event/ApplicationEvent'
|
||||||
import { ApplicationEventCallback } from '../Event/ApplicationEventCallback'
|
import { ApplicationEventCallback } from '../Event/ApplicationEventCallback'
|
||||||
import { FeaturesClientInterface } from '../Feature/FeaturesClientInterface'
|
import { FeaturesClientInterface } from '../Feature/FeaturesClientInterface'
|
||||||
|
import { SubscriptionClientInterface } from '../Subscription/SubscriptionClientInterface'
|
||||||
import { ItemsClientInterface } from '../Item/ItemsClientInterface'
|
import { ItemsClientInterface } from '../Item/ItemsClientInterface'
|
||||||
import { MutatorClientInterface } from '../Mutator/MutatorClientInterface'
|
import { MutatorClientInterface } from '../Mutator/MutatorClientInterface'
|
||||||
import { StorageValueModes } from '../Storage/StorageTypes'
|
import { StorageValueModes } from '../Storage/StorageTypes'
|
||||||
@@ -48,6 +48,7 @@ export interface ApplicationInterface {
|
|||||||
get mutator(): MutatorClientInterface
|
get mutator(): MutatorClientInterface
|
||||||
get user(): UserClientInterface
|
get user(): UserClientInterface
|
||||||
get files(): FilesClientInterface
|
get files(): FilesClientInterface
|
||||||
|
get subscriptions(): SubscriptionClientInterface
|
||||||
readonly identifier: ApplicationIdentifier
|
readonly identifier: ApplicationIdentifier
|
||||||
readonly platform: Platform
|
readonly platform: Platform
|
||||||
deviceInterface: DeviceInterface
|
deviceInterface: DeviceInterface
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
import { Environment } from '@standardnotes/models'
|
||||||
|
|
||||||
import { WebClientRequiresDesktopMethods } from './DesktopWebCommunication'
|
import { WebClientRequiresDesktopMethods } from './DesktopWebCommunication'
|
||||||
import { DeviceInterface } from './DeviceInterface'
|
import { DeviceInterface } from './DeviceInterface'
|
||||||
import { Environment } from './Environments'
|
|
||||||
import { WebOrDesktopDeviceInterface } from './WebOrDesktopDeviceInterface'
|
import { WebOrDesktopDeviceInterface } from './WebOrDesktopDeviceInterface'
|
||||||
|
|
||||||
/* istanbul ignore file */
|
/* istanbul ignore file */
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Environment } from './Environments'
|
|
||||||
import { ApplicationIdentifier } from '@standardnotes/common'
|
import { ApplicationIdentifier } from '@standardnotes/common'
|
||||||
import {
|
import {
|
||||||
FullyFormedTransferPayload,
|
FullyFormedTransferPayload,
|
||||||
TransferPayload,
|
TransferPayload,
|
||||||
LegacyRawKeychainValue,
|
LegacyRawKeychainValue,
|
||||||
NamespacedRootKeyInKeychain,
|
NamespacedRootKeyInKeychain,
|
||||||
|
Environment,
|
||||||
} from '@standardnotes/models'
|
} from '@standardnotes/models'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { DeviceInterface } from './DeviceInterface'
|
import { DeviceInterface } from './DeviceInterface'
|
||||||
import { Environment } from './Environments'
|
import { Environment, RawKeychainValue } from '@standardnotes/models'
|
||||||
import { RawKeychainValue } from '@standardnotes/models'
|
|
||||||
|
|
||||||
export interface MobileDeviceInterface extends DeviceInterface {
|
export interface MobileDeviceInterface extends DeviceInterface {
|
||||||
environment: Environment.Mobile
|
environment: Environment.Mobile
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
import { Environment } from '@standardnotes/models'
|
||||||
|
|
||||||
import { DeviceInterface } from './DeviceInterface'
|
import { DeviceInterface } from './DeviceInterface'
|
||||||
import { Environment } from './Environments'
|
|
||||||
import { MobileDeviceInterface } from './MobileDeviceInterface'
|
import { MobileDeviceInterface } from './MobileDeviceInterface'
|
||||||
import { isMobileDevice } from './TypeCheck'
|
import { isMobileDevice } from './TypeCheck'
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Environment } from './Environments'
|
|
||||||
import { MobileDeviceInterface } from './MobileDeviceInterface'
|
import { MobileDeviceInterface } from './MobileDeviceInterface'
|
||||||
import { DeviceInterface } from './DeviceInterface'
|
import { DeviceInterface } from './DeviceInterface'
|
||||||
|
import { Environment } from '@standardnotes/models'
|
||||||
|
|
||||||
/* istanbul ignore file */
|
/* istanbul ignore file */
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { Uuid } from '@standardnotes/common'
|
||||||
|
import { Invitation } from '@standardnotes/models'
|
||||||
|
|
||||||
|
export interface SubscriptionClientInterface {
|
||||||
|
listSubscriptionInvitations(): Promise<Invitation[]>
|
||||||
|
inviteToSubscription(inviteeEmail: string): Promise<boolean>
|
||||||
|
cancelInvitation(inviteUuid: Uuid): Promise<boolean>
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import { SubscriptionApiServiceInterface } from '@standardnotes/api'
|
||||||
|
import { Invitation } from '@standardnotes/models'
|
||||||
|
import { InternalEventBusInterface } from '..'
|
||||||
|
import { SubscriptionManager } from './SubscriptionManager'
|
||||||
|
|
||||||
|
describe('SubscriptionManager', () => {
|
||||||
|
let subscriptionApiService: SubscriptionApiServiceInterface
|
||||||
|
let internalEventBus: InternalEventBusInterface
|
||||||
|
|
||||||
|
const createManager = () => new SubscriptionManager(subscriptionApiService, internalEventBus)
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
subscriptionApiService = {} as jest.Mocked<SubscriptionApiServiceInterface>
|
||||||
|
subscriptionApiService.cancelInvite = jest.fn()
|
||||||
|
subscriptionApiService.invite = jest.fn()
|
||||||
|
subscriptionApiService.listInvites = jest.fn()
|
||||||
|
|
||||||
|
internalEventBus = {} as jest.Mocked<InternalEventBusInterface>
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should invite user by email to a shared subscription', async () => {
|
||||||
|
subscriptionApiService.invite = jest.fn().mockReturnValue({ data: { success: true } })
|
||||||
|
|
||||||
|
expect(await createManager().inviteToSubscription('test@test.te')).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not invite user by email if the api fails to do so', async () => {
|
||||||
|
subscriptionApiService.invite = jest.fn().mockReturnValue({ data: { error: 'foobar' } })
|
||||||
|
|
||||||
|
expect(await createManager().inviteToSubscription('test@test.te')).toBeFalsy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not invite user by email if the api throws an error', async () => {
|
||||||
|
subscriptionApiService.invite = jest.fn().mockImplementation(() => {
|
||||||
|
throw new Error('Oops')
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(await createManager().inviteToSubscription('test@test.te')).toBeFalsy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should cancel invite to a shared subscription', async () => {
|
||||||
|
subscriptionApiService.cancelInvite = jest.fn().mockReturnValue({ data: { success: true } })
|
||||||
|
|
||||||
|
expect(await createManager().cancelInvitation('1-2-3')).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not cancel invite if the api fails to do so', async () => {
|
||||||
|
subscriptionApiService.cancelInvite = jest.fn().mockReturnValue({ data: { error: 'foobar' } })
|
||||||
|
|
||||||
|
expect(await createManager().cancelInvitation('1-2-3')).toBeFalsy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not cancel invite if the api throws an error', async () => {
|
||||||
|
subscriptionApiService.cancelInvite = jest.fn().mockImplementation(() => {
|
||||||
|
throw new Error('Oops')
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(await createManager().cancelInvitation('1-2-3')).toBeFalsy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should list invites to a shared subscription', async () => {
|
||||||
|
const invitation = {
|
||||||
|
uuid: '1-2-3',
|
||||||
|
} as jest.Mocked<Invitation>
|
||||||
|
subscriptionApiService.listInvites = jest.fn().mockReturnValue({ data: { invitations: [invitation] } })
|
||||||
|
|
||||||
|
expect(await createManager().listSubscriptionInvitations()).toEqual([invitation])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return an empty list of invites if the api fails to fetch them', async () => {
|
||||||
|
subscriptionApiService.listInvites = jest.fn().mockReturnValue({ data: { error: 'foobar' } })
|
||||||
|
|
||||||
|
expect(await createManager().listSubscriptionInvitations()).toEqual([])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return an empty list of invites if the api throws an error', async () => {
|
||||||
|
subscriptionApiService.listInvites = jest.fn().mockImplementation(() => {
|
||||||
|
throw new Error('Oops')
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(await createManager().listSubscriptionInvitations()).toEqual([])
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { Invitation } from '@standardnotes/models'
|
||||||
|
import { SubscriptionApiServiceInterface } from '@standardnotes/api'
|
||||||
|
import { InternalEventBusInterface } from '../Internal/InternalEventBusInterface'
|
||||||
|
import { AbstractService } from '../Service/AbstractService'
|
||||||
|
import { SubscriptionClientInterface } from './SubscriptionClientInterface'
|
||||||
|
import { Uuid } from '@standardnotes/common'
|
||||||
|
|
||||||
|
export class SubscriptionManager extends AbstractService implements SubscriptionClientInterface {
|
||||||
|
constructor(
|
||||||
|
private subscriptionApiService: SubscriptionApiServiceInterface,
|
||||||
|
protected override internalEventBus: InternalEventBusInterface,
|
||||||
|
) {
|
||||||
|
super(internalEventBus)
|
||||||
|
}
|
||||||
|
|
||||||
|
async listSubscriptionInvitations(): Promise<Invitation[]> {
|
||||||
|
try {
|
||||||
|
const response = await this.subscriptionApiService.listInvites()
|
||||||
|
|
||||||
|
return response.data.invitations ?? []
|
||||||
|
} catch (error) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async inviteToSubscription(inviteeEmail: string): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
const result = await this.subscriptionApiService.invite(inviteeEmail)
|
||||||
|
|
||||||
|
return result.data.success === true
|
||||||
|
} catch (error) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async cancelInvitation(inviteUuid: Uuid): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
const result = await this.subscriptionApiService.cancelInvite(inviteUuid)
|
||||||
|
|
||||||
|
return result.data.success === true
|
||||||
|
} catch (error) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@ export * from './Device/DesktopDeviceInterface'
|
|||||||
export * from './Device/DesktopManagerInterface'
|
export * from './Device/DesktopManagerInterface'
|
||||||
export * from './Device/DesktopWebCommunication'
|
export * from './Device/DesktopWebCommunication'
|
||||||
export * from './Device/DeviceInterface'
|
export * from './Device/DeviceInterface'
|
||||||
export * from './Device/Environments'
|
|
||||||
export * from './Device/MobileDeviceInterface'
|
export * from './Device/MobileDeviceInterface'
|
||||||
export * from './Device/TypeCheck'
|
export * from './Device/TypeCheck'
|
||||||
export * from './Device/WebOrDesktopDeviceInterface'
|
export * from './Device/WebOrDesktopDeviceInterface'
|
||||||
@@ -67,6 +66,8 @@ export * from './Storage/InMemoryStore'
|
|||||||
export * from './Storage/KeyValueStoreInterface'
|
export * from './Storage/KeyValueStoreInterface'
|
||||||
export * from './Storage/StorageServiceInterface'
|
export * from './Storage/StorageServiceInterface'
|
||||||
export * from './Storage/StorageTypes'
|
export * from './Storage/StorageTypes'
|
||||||
|
export * from './Subscription/SubscriptionClientInterface'
|
||||||
|
export * from './Subscription/SubscriptionManager'
|
||||||
export * from './Sync/SyncMode'
|
export * from './Sync/SyncMode'
|
||||||
export * from './Sync/SyncOptions'
|
export * from './Sync/SyncOptions'
|
||||||
export * from './Sync/SyncQueueStrategy'
|
export * from './Sync/SyncQueueStrategy'
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
import { SNLog } from './../Log'
|
import { SNLog } from './../Log'
|
||||||
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
|
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
|
||||||
import {
|
import { AlertService, DeviceInterface, namespacedKey, RawStorageKey } from '@standardnotes/services'
|
||||||
AlertService,
|
import { Environment, Platform } from '@standardnotes/models'
|
||||||
DeviceInterface,
|
|
||||||
Environment,
|
|
||||||
namespacedKey,
|
|
||||||
Platform,
|
|
||||||
RawStorageKey,
|
|
||||||
} from '@standardnotes/services'
|
|
||||||
import { SNApplication } from './Application'
|
import { SNApplication } from './Application'
|
||||||
|
|
||||||
describe('application', () => {
|
describe('application', () => {
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
HttpService,
|
HttpService,
|
||||||
HttpServiceInterface,
|
HttpServiceInterface,
|
||||||
|
SubscriptionApiService,
|
||||||
|
SubscriptionApiServiceInterface,
|
||||||
|
SubscriptionServer,
|
||||||
|
SubscriptionServerInterface,
|
||||||
UserApiService,
|
UserApiService,
|
||||||
UserApiServiceInterface,
|
UserApiServiceInterface,
|
||||||
UserRegistrationResponseBody,
|
UserRegistrationResponseBody,
|
||||||
@@ -23,9 +27,7 @@ import {
|
|||||||
ChallengeValidation,
|
ChallengeValidation,
|
||||||
ComponentManagerInterface,
|
ComponentManagerInterface,
|
||||||
DiagnosticInfo,
|
DiagnosticInfo,
|
||||||
Environment,
|
|
||||||
isDesktopDevice,
|
isDesktopDevice,
|
||||||
Platform,
|
|
||||||
ChallengeValue,
|
ChallengeValue,
|
||||||
StorageKey,
|
StorageKey,
|
||||||
ChallengeReason,
|
ChallengeReason,
|
||||||
@@ -37,11 +39,20 @@ import {
|
|||||||
EncryptionServiceEvent,
|
EncryptionServiceEvent,
|
||||||
FilesBackupService,
|
FilesBackupService,
|
||||||
FileService,
|
FileService,
|
||||||
|
SubscriptionClientInterface,
|
||||||
|
SubscriptionManager,
|
||||||
} from '@standardnotes/services'
|
} from '@standardnotes/services'
|
||||||
import { FilesClientInterface } from '@standardnotes/files'
|
import { FilesClientInterface } from '@standardnotes/files'
|
||||||
import { ComputePrivateWorkspaceIdentifier } from '@standardnotes/encryption'
|
import { ComputePrivateWorkspaceIdentifier } from '@standardnotes/encryption'
|
||||||
import { useBoolean } from '@standardnotes/utils'
|
import { useBoolean } from '@standardnotes/utils'
|
||||||
import { BackupFile, DecryptedItemInterface, EncryptedItemInterface, ItemStream } from '@standardnotes/models'
|
import {
|
||||||
|
BackupFile,
|
||||||
|
DecryptedItemInterface,
|
||||||
|
EncryptedItemInterface,
|
||||||
|
Environment,
|
||||||
|
ItemStream,
|
||||||
|
Platform,
|
||||||
|
} from '@standardnotes/models'
|
||||||
import { ClientDisplayableError } from '@standardnotes/responses'
|
import { ClientDisplayableError } from '@standardnotes/responses'
|
||||||
|
|
||||||
import { SnjsVersion } from './../Version'
|
import { SnjsVersion } from './../Version'
|
||||||
@@ -92,6 +103,9 @@ export class SNApplication
|
|||||||
private apiService!: InternalServices.SNApiService
|
private apiService!: InternalServices.SNApiService
|
||||||
private declare userApiService: UserApiServiceInterface
|
private declare userApiService: UserApiServiceInterface
|
||||||
private declare userServer: UserServerInterface
|
private declare userServer: UserServerInterface
|
||||||
|
private declare subscriptionApiService: SubscriptionApiServiceInterface
|
||||||
|
private declare subscriptionServer: SubscriptionServerInterface
|
||||||
|
private declare subscriptionManager: SubscriptionClientInterface
|
||||||
private sessionManager!: InternalServices.SNSessionManager
|
private sessionManager!: InternalServices.SNSessionManager
|
||||||
private syncService!: InternalServices.SNSyncService
|
private syncService!: InternalServices.SNSyncService
|
||||||
private challengeService!: InternalServices.ChallengeService
|
private challengeService!: InternalServices.ChallengeService
|
||||||
@@ -187,6 +201,10 @@ export class SNApplication
|
|||||||
this.defineInternalEventHandlers()
|
this.defineInternalEventHandlers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get subscriptions(): ExternalServices.SubscriptionClientInterface {
|
||||||
|
return this.subscriptionManager
|
||||||
|
}
|
||||||
|
|
||||||
public get files(): FilesClientInterface {
|
public get files(): FilesClientInterface {
|
||||||
return this.fileService
|
return this.fileService
|
||||||
}
|
}
|
||||||
@@ -1031,6 +1049,9 @@ export class SNApplication
|
|||||||
this.createHttpService()
|
this.createHttpService()
|
||||||
this.createUserServer()
|
this.createUserServer()
|
||||||
this.createUserApiService()
|
this.createUserApiService()
|
||||||
|
this.createSubscriptionServer()
|
||||||
|
this.createSubscriptionApiService()
|
||||||
|
this.createSubscriptionManager()
|
||||||
this.createWebSocketsService()
|
this.createWebSocketsService()
|
||||||
this.createSessionManager()
|
this.createSessionManager()
|
||||||
this.createHistoryManager()
|
this.createHistoryManager()
|
||||||
@@ -1069,6 +1090,9 @@ export class SNApplication
|
|||||||
;(this.apiService as unknown) = undefined
|
;(this.apiService as unknown) = undefined
|
||||||
;(this.userApiService as unknown) = undefined
|
;(this.userApiService as unknown) = undefined
|
||||||
;(this.userServer as unknown) = undefined
|
;(this.userServer as unknown) = undefined
|
||||||
|
;(this.subscriptionApiService as unknown) = undefined
|
||||||
|
;(this.subscriptionServer as unknown) = undefined
|
||||||
|
;(this.subscriptionManager as unknown) = undefined
|
||||||
;(this.sessionManager as unknown) = undefined
|
;(this.sessionManager as unknown) = undefined
|
||||||
;(this.syncService as unknown) = undefined
|
;(this.syncService as unknown) = undefined
|
||||||
;(this.challengeService as unknown) = undefined
|
;(this.challengeService as unknown) = undefined
|
||||||
@@ -1262,6 +1286,18 @@ export class SNApplication
|
|||||||
this.userServer = new UserServer(this.httpService)
|
this.userServer = new UserServer(this.httpService)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private createSubscriptionApiService() {
|
||||||
|
this.subscriptionApiService = new SubscriptionApiService(this.subscriptionServer)
|
||||||
|
}
|
||||||
|
|
||||||
|
private createSubscriptionServer() {
|
||||||
|
this.subscriptionServer = new SubscriptionServer(this.httpService)
|
||||||
|
}
|
||||||
|
|
||||||
|
private createSubscriptionManager() {
|
||||||
|
this.subscriptionManager = new SubscriptionManager(this.subscriptionApiService, this.internalEventBus)
|
||||||
|
}
|
||||||
|
|
||||||
private createItemManager() {
|
private createItemManager() {
|
||||||
this.itemManager = new InternalServices.ItemManager(this.payloadManager, this.options, this.internalEventBus)
|
this.itemManager = new InternalServices.ItemManager(this.payloadManager, this.options, this.internalEventBus)
|
||||||
this.services.push(this.itemManager)
|
this.services.push(this.itemManager)
|
||||||
@@ -1377,6 +1413,7 @@ export class SNApplication
|
|||||||
this.protocolService,
|
this.protocolService,
|
||||||
this.challengeService,
|
this.challengeService,
|
||||||
this.webSocketsService,
|
this.webSocketsService,
|
||||||
|
this.httpService,
|
||||||
this.internalEventBus,
|
this.internalEventBus,
|
||||||
)
|
)
|
||||||
this.serviceObservers.push(
|
this.serviceObservers.push(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
import { Environment, Platform } from '@standardnotes/models'
|
||||||
import { ApplicationIdentifier } from '@standardnotes/common'
|
import { ApplicationIdentifier } from '@standardnotes/common'
|
||||||
import { AlertService, DeviceInterface, Environment, Platform } from '@standardnotes/services'
|
import { AlertService, DeviceInterface } from '@standardnotes/services'
|
||||||
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
|
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
|
||||||
|
|
||||||
export interface RequiredApplicationOptions {
|
export interface RequiredApplicationOptions {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Environment, Platform } from '@standardnotes/services'
|
import { Environment, Platform } from '@standardnotes/models'
|
||||||
|
|
||||||
export function platformFromString(string: string) {
|
export function platformFromString(string: string) {
|
||||||
const map: Record<string, Platform> = {
|
const map: Record<string, Platform> = {
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
import { Environment } from '@standardnotes/models'
|
||||||
|
import { DeviceInterface, InternalEventBusInterface, EncryptionService } from '@standardnotes/services'
|
||||||
|
|
||||||
import { SNSessionManager } from '../Services/Session/SessionManager'
|
import { SNSessionManager } from '../Services/Session/SessionManager'
|
||||||
import { ApplicationIdentifier } from '@standardnotes/common'
|
import { ApplicationIdentifier } from '@standardnotes/common'
|
||||||
import { ItemManager } from '@Lib/Services/Items/ItemManager'
|
import { ItemManager } from '@Lib/Services/Items/ItemManager'
|
||||||
import { DeviceInterface, InternalEventBusInterface, Environment, EncryptionService } from '@standardnotes/services'
|
|
||||||
import { ChallengeService, SNSingletonManager, SNFeaturesService, DiskStorageService } from '@Lib/Services'
|
import { ChallengeService, SNSingletonManager, SNFeaturesService, DiskStorageService } from '@Lib/Services'
|
||||||
|
|
||||||
export type MigrationServices = {
|
export type MigrationServices = {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ApplicationIdentifier } from '@standardnotes/common'
|
import { ApplicationIdentifier } from '@standardnotes/common'
|
||||||
|
import { Environment } from '@standardnotes/models'
|
||||||
import { compareSemVersions, isRightVersionGreaterThanLeft } from '@Lib/Version'
|
import { compareSemVersions, isRightVersionGreaterThanLeft } from '@Lib/Version'
|
||||||
import { DeviceInterface, Environment } from '@standardnotes/services'
|
import { DeviceInterface } from '@standardnotes/services'
|
||||||
import { StorageReader } from './Reader'
|
import { StorageReader } from './Reader'
|
||||||
import * as ReaderClasses from './Versions'
|
import * as ReaderClasses from './Versions'
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
import { Environment } from '@standardnotes/models'
|
||||||
import { ApplicationIdentifier } from '@standardnotes/common'
|
import { ApplicationIdentifier } from '@standardnotes/common'
|
||||||
import { DeviceInterface, Environment } from '@standardnotes/services'
|
import { DeviceInterface } from '@standardnotes/services'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A storage reader reads storage via a device interface
|
* A storage reader reads storage via a device interface
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import { API_MESSAGE_RATE_LIMITED, UNKNOWN_ERROR } from './Messages'
|
|||||||
import { HttpResponse, StatusCode } from '@standardnotes/responses'
|
import { HttpResponse, StatusCode } from '@standardnotes/responses'
|
||||||
import { isString } from '@standardnotes/utils'
|
import { isString } from '@standardnotes/utils'
|
||||||
import { SnjsVersion } from '@Lib/Version'
|
import { SnjsVersion } from '@Lib/Version'
|
||||||
import { AbstractService, InternalEventBusInterface, Environment } from '@standardnotes/services'
|
import { AbstractService, InternalEventBusInterface } from '@standardnotes/services'
|
||||||
|
import { Environment } from '@standardnotes/models'
|
||||||
|
|
||||||
export enum HttpVerb {
|
export enum HttpVerb {
|
||||||
Get = 'GET',
|
Get = 'GET',
|
||||||
|
|||||||
@@ -11,14 +11,8 @@ import {
|
|||||||
FeatureIdentifier,
|
FeatureIdentifier,
|
||||||
} from '@standardnotes/features'
|
} from '@standardnotes/features'
|
||||||
import { ContentType } from '@standardnotes/common'
|
import { ContentType } from '@standardnotes/common'
|
||||||
import { GenericItem, SNComponent } from '@standardnotes/models'
|
import { GenericItem, SNComponent, Environment, Platform } from '@standardnotes/models'
|
||||||
import {
|
import { DesktopManagerInterface, InternalEventBusInterface, AlertService } from '@standardnotes/services'
|
||||||
DesktopManagerInterface,
|
|
||||||
InternalEventBusInterface,
|
|
||||||
Environment,
|
|
||||||
Platform,
|
|
||||||
AlertService,
|
|
||||||
} from '@standardnotes/services'
|
|
||||||
import { ItemManager } from '@Lib/Services/Items/ItemManager'
|
import { ItemManager } from '@Lib/Services/Items/ItemManager'
|
||||||
import { SNFeaturesService } from '@Lib/Services/Features/FeaturesService'
|
import { SNFeaturesService } from '@Lib/Services/Features/FeaturesService'
|
||||||
import { SNComponentManager } from './ComponentManager'
|
import { SNComponentManager } from './ComponentManager'
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import {
|
|||||||
ComponentMutator,
|
ComponentMutator,
|
||||||
PayloadEmitSource,
|
PayloadEmitSource,
|
||||||
PermissionDialog,
|
PermissionDialog,
|
||||||
|
Environment,
|
||||||
|
Platform,
|
||||||
} from '@standardnotes/models'
|
} from '@standardnotes/models'
|
||||||
import { SNSyncService } from '@Lib/Services/Sync/SyncService'
|
import { SNSyncService } from '@Lib/Services/Sync/SyncService'
|
||||||
import find from 'lodash/find'
|
import find from 'lodash/find'
|
||||||
@@ -26,8 +28,6 @@ import {
|
|||||||
ComponentViewerInterface,
|
ComponentViewerInterface,
|
||||||
DesktopManagerInterface,
|
DesktopManagerInterface,
|
||||||
InternalEventBusInterface,
|
InternalEventBusInterface,
|
||||||
Environment,
|
|
||||||
Platform,
|
|
||||||
AlertService,
|
AlertService,
|
||||||
} from '@standardnotes/services'
|
} from '@standardnotes/services'
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ import { SNPreferencesService } from '../Preferences/PreferencesService'
|
|||||||
import {
|
import {
|
||||||
ComponentViewerInterface,
|
ComponentViewerInterface,
|
||||||
ComponentViewerError,
|
ComponentViewerError,
|
||||||
Environment,
|
|
||||||
FeatureStatus,
|
FeatureStatus,
|
||||||
FeaturesEvent,
|
FeaturesEvent,
|
||||||
Platform,
|
|
||||||
AlertService,
|
AlertService,
|
||||||
} from '@standardnotes/services'
|
} from '@standardnotes/services'
|
||||||
import { SNFeaturesService } from '@Lib/Services'
|
import { SNFeaturesService } from '@Lib/Services'
|
||||||
@@ -34,6 +32,8 @@ import {
|
|||||||
PayloadTimestampDefaults,
|
PayloadTimestampDefaults,
|
||||||
IncomingComponentItemPayload,
|
IncomingComponentItemPayload,
|
||||||
MessageData,
|
MessageData,
|
||||||
|
Environment,
|
||||||
|
Platform,
|
||||||
} from '@standardnotes/models'
|
} from '@standardnotes/models'
|
||||||
import find from 'lodash/find'
|
import find from 'lodash/find'
|
||||||
import uniq from 'lodash/uniq'
|
import uniq from 'lodash/uniq'
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import {
|
|||||||
ApiCallError,
|
ApiCallError,
|
||||||
ErrorMessage,
|
ErrorMessage,
|
||||||
HttpErrorResponseBody,
|
HttpErrorResponseBody,
|
||||||
|
HttpServiceInterface,
|
||||||
UserApiServiceInterface,
|
UserApiServiceInterface,
|
||||||
UserRegistrationResponseBody,
|
UserRegistrationResponseBody,
|
||||||
} from '@standardnotes/api'
|
} from '@standardnotes/api'
|
||||||
@@ -77,6 +78,7 @@ export class SNSessionManager extends AbstractService<SessionEvent> implements S
|
|||||||
private protocolService: EncryptionService,
|
private protocolService: EncryptionService,
|
||||||
private challengeService: ChallengeService,
|
private challengeService: ChallengeService,
|
||||||
private webSocketsService: SNWebSocketsService,
|
private webSocketsService: SNWebSocketsService,
|
||||||
|
private httpService: HttpServiceInterface,
|
||||||
protected override internalEventBus: InternalEventBusInterface,
|
protected override internalEventBus: InternalEventBusInterface,
|
||||||
) {
|
) {
|
||||||
super(internalEventBus)
|
super(internalEventBus)
|
||||||
@@ -617,6 +619,10 @@ export class SNSessionManager extends AbstractService<SessionEvent> implements S
|
|||||||
|
|
||||||
void this.apiService.setHost(host)
|
void this.apiService.setHost(host)
|
||||||
|
|
||||||
|
this.httpService.setHost(host)
|
||||||
|
|
||||||
|
this.httpService.setAuthorizationToken(session.authorizationValue)
|
||||||
|
|
||||||
await this.setSession(session)
|
await this.setSession(session)
|
||||||
|
|
||||||
this.webSocketsService.startWebSocketConnection(session.authorizationValue)
|
this.webSocketsService.startWebSocketConnection(session.authorizationValue)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { SNLog } from '../../Log'
|
|||||||
import { isErrorDecryptingParameters, SNRootKey } from '@standardnotes/encryption'
|
import { isErrorDecryptingParameters, SNRootKey } from '@standardnotes/encryption'
|
||||||
import * as Encryption from '@standardnotes/encryption'
|
import * as Encryption from '@standardnotes/encryption'
|
||||||
import * as Services from '@standardnotes/services'
|
import * as Services from '@standardnotes/services'
|
||||||
import { DiagnosticInfo, Environment } from '@standardnotes/services'
|
import { DiagnosticInfo } from '@standardnotes/services'
|
||||||
import {
|
import {
|
||||||
CreateDecryptedLocalStorageContextPayload,
|
CreateDecryptedLocalStorageContextPayload,
|
||||||
CreateDeletedLocalStorageContextPayload,
|
CreateDeletedLocalStorageContextPayload,
|
||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
DeletedPayloadInterface,
|
DeletedPayloadInterface,
|
||||||
PayloadTimestampDefaults,
|
PayloadTimestampDefaults,
|
||||||
LocalStorageEncryptedContextualPayload,
|
LocalStorageEncryptedContextualPayload,
|
||||||
|
Environment,
|
||||||
} from '@standardnotes/models'
|
} from '@standardnotes/models'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
110
packages/snjs/mocha/subscriptions.test.js
Normal file
110
packages/snjs/mocha/subscriptions.test.js
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import * as Factory from './lib/factory.js'
|
||||||
|
chai.use(chaiAsPromised)
|
||||||
|
const expect = chai.expect
|
||||||
|
|
||||||
|
describe('subscriptions', function () {
|
||||||
|
this.timeout(Factory.TwentySecondTimeout)
|
||||||
|
|
||||||
|
let application
|
||||||
|
let context
|
||||||
|
let subscriptionManager
|
||||||
|
|
||||||
|
afterEach(async function () {
|
||||||
|
await Factory.safeDeinit(application)
|
||||||
|
localStorage.clear()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async function () {
|
||||||
|
localStorage.clear()
|
||||||
|
|
||||||
|
context = await Factory.createAppContextWithFakeCrypto()
|
||||||
|
|
||||||
|
await context.launch()
|
||||||
|
|
||||||
|
application = context.application
|
||||||
|
subscriptionManager = context.application.subscriptionManager
|
||||||
|
|
||||||
|
const result = await Factory.registerUserToApplication({
|
||||||
|
application: application,
|
||||||
|
email: context.email,
|
||||||
|
password: context.password,
|
||||||
|
})
|
||||||
|
|
||||||
|
await Factory.publishMockedEvent('SUBSCRIPTION_PURCHASED', {
|
||||||
|
userEmail: context.email,
|
||||||
|
subscriptionId: 1,
|
||||||
|
subscriptionName: 'PRO_PLAN',
|
||||||
|
subscriptionExpiresAt: (new Date().getTime() + 3_600_000) * 1_000,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
offline: false,
|
||||||
|
})
|
||||||
|
await Factory.sleep(0.25)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should invite a user by email to a shared subscription', async () => {
|
||||||
|
await subscriptionManager.inviteToSubscription('test@test.te')
|
||||||
|
|
||||||
|
const existingInvites = await subscriptionManager.listSubscriptionInvitations()
|
||||||
|
|
||||||
|
const newlyCreatedInvite = existingInvites.find(invite => invite.inviteeIdentifier === 'test@test.te')
|
||||||
|
|
||||||
|
expect(newlyCreatedInvite.status).to.equal('sent')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not invite a user by email if the limit of shared subscription is breached', async () => {
|
||||||
|
await subscriptionManager.inviteToSubscription('test1@test.te')
|
||||||
|
await subscriptionManager.inviteToSubscription('test2@test.te')
|
||||||
|
await subscriptionManager.inviteToSubscription('test3@test.te')
|
||||||
|
await subscriptionManager.inviteToSubscription('test4@test.te')
|
||||||
|
await subscriptionManager.inviteToSubscription('test5@test.te')
|
||||||
|
|
||||||
|
let existingInvites = await subscriptionManager.listSubscriptionInvitations()
|
||||||
|
|
||||||
|
expect(existingInvites.length).to.equal(5)
|
||||||
|
|
||||||
|
expect(await subscriptionManager.inviteToSubscription('test6@test.te')).to.equal(false)
|
||||||
|
|
||||||
|
existingInvites = await subscriptionManager.listSubscriptionInvitations()
|
||||||
|
|
||||||
|
expect(existingInvites.length).to.equal(5)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should cancel a user invitation to a shared subscription', async () => {
|
||||||
|
await subscriptionManager.inviteToSubscription('test@test.te')
|
||||||
|
await subscriptionManager.inviteToSubscription('test2@test.te')
|
||||||
|
|
||||||
|
let existingInvites = await subscriptionManager.listSubscriptionInvitations()
|
||||||
|
|
||||||
|
expect (existingInvites.length).to.equal(2)
|
||||||
|
|
||||||
|
const newlyCreatedInvite = existingInvites.find(invite => invite.inviteeIdentifier === 'test@test.te')
|
||||||
|
|
||||||
|
await subscriptionManager.cancelInvitation(newlyCreatedInvite.uuid)
|
||||||
|
|
||||||
|
existingInvites = await subscriptionManager.listSubscriptionInvitations()
|
||||||
|
|
||||||
|
expect (existingInvites.length).to.equal(2)
|
||||||
|
|
||||||
|
expect(existingInvites.filter(invite => invite.status === 'canceled').length).to.equal(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should invite a user by email if the limit of shared subscription is restored', async () => {
|
||||||
|
await subscriptionManager.inviteToSubscription('test1@test.te')
|
||||||
|
await subscriptionManager.inviteToSubscription('test2@test.te')
|
||||||
|
await subscriptionManager.inviteToSubscription('test3@test.te')
|
||||||
|
await subscriptionManager.inviteToSubscription('test4@test.te')
|
||||||
|
await subscriptionManager.inviteToSubscription('test5@test.te')
|
||||||
|
|
||||||
|
let existingInvites = await subscriptionManager.listSubscriptionInvitations()
|
||||||
|
|
||||||
|
expect(existingInvites.length).to.equal(5)
|
||||||
|
|
||||||
|
await subscriptionManager.cancelInvitation(existingInvites[0].uuid)
|
||||||
|
|
||||||
|
expect(await subscriptionManager.inviteToSubscription('test6@test.te')).to.equal(true)
|
||||||
|
|
||||||
|
existingInvites = await subscriptionManager.listSubscriptionInvitations()
|
||||||
|
|
||||||
|
expect(existingInvites.find(invite => invite.inviteeIdentifier === 'test6@test.te')).not.to.equal(undefined)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -91,6 +91,7 @@
|
|||||||
<script type="module" src="session-sharing.test.js"></script>
|
<script type="module" src="session-sharing.test.js"></script>
|
||||||
<script type="module" src="files.test.js"></script>
|
<script type="module" src="files.test.js"></script>
|
||||||
<script type="module" src="session.test.js"></script>
|
<script type="module" src="session.test.js"></script>
|
||||||
|
<script type="module" src="subscriptions.test.js"></script>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
mocha.run();
|
mocha.run();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
"tsc": "tsc --project lib/tsconfig.json && tscpaths -p lib/tsconfig.json -s lib -o dist/@types",
|
"tsc": "tsc --project lib/tsconfig.json && tscpaths -p lib/tsconfig.json -s lib -o dist/@types",
|
||||||
"lint": "yarn lint:tsc && yarn lint:eslint",
|
"lint": "yarn lint:tsc && yarn lint:eslint",
|
||||||
"lint:eslint": "eslint --ext .ts lib/",
|
"lint:eslint": "eslint --ext .ts lib/",
|
||||||
|
"lint:fix": "eslint --fix --ext .ts lib/",
|
||||||
"lint:tsc": "tsc --noEmit --emitDeclarationOnly false --project lib/tsconfig.json",
|
"lint:tsc": "tsc --noEmit --emitDeclarationOnly false --project lib/tsconfig.json",
|
||||||
"test": "jest spec --coverage",
|
"test": "jest spec --coverage",
|
||||||
"test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand"
|
"test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand"
|
||||||
@@ -67,7 +68,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standardnotes/api": "workspace:*",
|
"@standardnotes/api": "workspace:*",
|
||||||
"@standardnotes/common": "^1.25.0",
|
"@standardnotes/common": "^1.32.0",
|
||||||
"@standardnotes/domain-events": "^2.39.0",
|
"@standardnotes/domain-events": "^2.39.0",
|
||||||
"@standardnotes/encryption": "workspace:*",
|
"@standardnotes/encryption": "workspace:*",
|
||||||
"@standardnotes/features": "workspace:*",
|
"@standardnotes/features": "workspace:*",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"test": "jest spec --coverage --passWithNoTests"
|
"test": "jest spec --coverage --passWithNoTests"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standardnotes/common": "^1.30.0",
|
"@standardnotes/common": "^1.32.0",
|
||||||
"@standardnotes/filepicker": "workspace:^",
|
"@standardnotes/filepicker": "workspace:^",
|
||||||
"@standardnotes/services": "workspace:^",
|
"@standardnotes/services": "workspace:^",
|
||||||
"@standardnotes/styles": "workspace:^",
|
"@standardnotes/styles": "workspace:^",
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
"test": "jest spec"
|
"test": "jest spec"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standardnotes/common": "^1.23.1",
|
"@standardnotes/common": "^1.32.0",
|
||||||
"dompurify": "^2.3.8",
|
"dompurify": "^2.3.8",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"reflect-metadata": "^0.1.13"
|
"reflect-metadata": "^0.1.13"
|
||||||
|
|||||||
110
yarn.lock
110
yarn.lock
@@ -3480,6 +3480,23 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@eslint/eslintrc@npm:^1.3.2":
|
||||||
|
version: 1.3.2
|
||||||
|
resolution: "@eslint/eslintrc@npm:1.3.2"
|
||||||
|
dependencies:
|
||||||
|
ajv: ^6.12.4
|
||||||
|
debug: ^4.3.2
|
||||||
|
espree: ^9.4.0
|
||||||
|
globals: ^13.15.0
|
||||||
|
ignore: ^5.2.0
|
||||||
|
import-fresh: ^3.2.1
|
||||||
|
js-yaml: ^4.1.0
|
||||||
|
minimatch: ^3.1.2
|
||||||
|
strip-json-comments: ^3.1.1
|
||||||
|
checksum: 2074dca47d7e1c5c6323ff353f690f4b25d3ab53fe7d27337e2592d37a894cf60ca0e85ca66b50ff2db0bc7e630cc1e9c7347d65bb185b61416565584c38999c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@expo/react-native-action-sheet@npm:^3.13.0":
|
"@expo/react-native-action-sheet@npm:^3.13.0":
|
||||||
version: 3.13.0
|
version: 3.13.0
|
||||||
resolution: "@expo/react-native-action-sheet@npm:3.13.0"
|
resolution: "@expo/react-native-action-sheet@npm:3.13.0"
|
||||||
@@ -6226,16 +6243,15 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@standardnotes/api@workspace:*, @standardnotes/api@workspace:packages/api":
|
"@standardnotes/api@workspace:*, @standardnotes/api@workspace:^, @standardnotes/api@workspace:packages/api":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@standardnotes/api@workspace:packages/api"
|
resolution: "@standardnotes/api@workspace:packages/api"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/common": ^1.23.1
|
"@standardnotes/common": ^1.32.0
|
||||||
"@standardnotes/encryption": "workspace:*"
|
"@standardnotes/encryption": "workspace:*"
|
||||||
"@standardnotes/models": "workspace:*"
|
"@standardnotes/models": "workspace:*"
|
||||||
"@standardnotes/responses": "workspace:*"
|
"@standardnotes/responses": "workspace:*"
|
||||||
"@standardnotes/security": ^1.1.0
|
"@standardnotes/security": ^1.1.0
|
||||||
"@standardnotes/services": "workspace:*"
|
|
||||||
"@standardnotes/utils": "workspace:*"
|
"@standardnotes/utils": "workspace:*"
|
||||||
"@types/jest": ^28.1.5
|
"@types/jest": ^28.1.5
|
||||||
"@types/lodash": ^4.14.182
|
"@types/lodash": ^4.14.182
|
||||||
@@ -6397,7 +6413,7 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@standardnotes/common@npm:1.25.0, @standardnotes/common@npm:^1.25.0":
|
"@standardnotes/common@npm:1.25.0":
|
||||||
version: 1.25.0
|
version: 1.25.0
|
||||||
resolution: "@standardnotes/common@npm:1.25.0"
|
resolution: "@standardnotes/common@npm:1.25.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -6413,12 +6429,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@standardnotes/common@npm:^1.30.0":
|
"@standardnotes/common@npm:^1.32.0":
|
||||||
version: 1.30.0
|
version: 1.32.0
|
||||||
resolution: "@standardnotes/common@npm:1.30.0"
|
resolution: "@standardnotes/common@npm:1.32.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
reflect-metadata: ^0.1.13
|
reflect-metadata: ^0.1.13
|
||||||
checksum: 833b6e7f3ee4cfbf306769d7387073073204a3dd5cd9adaf11bb10914338a4b16420e5ef196d28974427b491d7630d887a7a9e3dcbfb070f30c491437213b329
|
checksum: 52d33f385e4cc26ac8d2f723c3a5e12bb8a2c4a17f08700ca5843810583ca722475a83b71f86bb1402fda7c7c66e8149beb3f70848efc90da4aafef663d7ffbe
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -6605,7 +6621,7 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@standardnotes/encryption@workspace:packages/encryption"
|
resolution: "@standardnotes/encryption@workspace:packages/encryption"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/common": ^1.23.1
|
"@standardnotes/common": ^1.32.0
|
||||||
"@standardnotes/config": 2.4.3
|
"@standardnotes/config": 2.4.3
|
||||||
"@standardnotes/models": "workspace:*"
|
"@standardnotes/models": "workspace:*"
|
||||||
"@standardnotes/responses": "workspace:*"
|
"@standardnotes/responses": "workspace:*"
|
||||||
@@ -6647,7 +6663,7 @@ __metadata:
|
|||||||
resolution: "@standardnotes/features@workspace:packages/features"
|
resolution: "@standardnotes/features@workspace:packages/features"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/auth": ^3.19.4
|
"@standardnotes/auth": ^3.19.4
|
||||||
"@standardnotes/common": ^1.23.1
|
"@standardnotes/common": ^1.32.0
|
||||||
"@standardnotes/security": ^1.2.0
|
"@standardnotes/security": ^1.2.0
|
||||||
"@types/jest": ^28.1.5
|
"@types/jest": ^28.1.5
|
||||||
"@typescript-eslint/eslint-plugin": ^5.30.0
|
"@typescript-eslint/eslint-plugin": ^5.30.0
|
||||||
@@ -6663,7 +6679,7 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@standardnotes/filepicker@workspace:packages/filepicker"
|
resolution: "@standardnotes/filepicker@workspace:packages/filepicker"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/common": ^1.23.1
|
"@standardnotes/common": ^1.32.0
|
||||||
"@standardnotes/files": "workspace:*"
|
"@standardnotes/files": "workspace:*"
|
||||||
"@standardnotes/utils": "workspace:*"
|
"@standardnotes/utils": "workspace:*"
|
||||||
"@types/jest": ^28.1.5
|
"@types/jest": ^28.1.5
|
||||||
@@ -6681,7 +6697,7 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@standardnotes/files@workspace:packages/files"
|
resolution: "@standardnotes/files@workspace:packages/files"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/common": ^1.23.1
|
"@standardnotes/common": ^1.32.0
|
||||||
"@standardnotes/encryption": "workspace:*"
|
"@standardnotes/encryption": "workspace:*"
|
||||||
"@standardnotes/models": "workspace:*"
|
"@standardnotes/models": "workspace:*"
|
||||||
"@standardnotes/responses": "workspace:*"
|
"@standardnotes/responses": "workspace:*"
|
||||||
@@ -7067,7 +7083,7 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@standardnotes/models@workspace:packages/models"
|
resolution: "@standardnotes/models@workspace:packages/models"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/common": ^1.23.1
|
"@standardnotes/common": ^1.32.0
|
||||||
"@standardnotes/features": "workspace:*"
|
"@standardnotes/features": "workspace:*"
|
||||||
"@standardnotes/responses": "workspace:*"
|
"@standardnotes/responses": "workspace:*"
|
||||||
"@standardnotes/utils": "workspace:*"
|
"@standardnotes/utils": "workspace:*"
|
||||||
@@ -7134,7 +7150,7 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@standardnotes/responses@workspace:packages/responses"
|
resolution: "@standardnotes/responses@workspace:packages/responses"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/common": ^1.23.1
|
"@standardnotes/common": ^1.32.0
|
||||||
"@standardnotes/features": "workspace:*"
|
"@standardnotes/features": "workspace:*"
|
||||||
"@standardnotes/security": ^1.1.0
|
"@standardnotes/security": ^1.1.0
|
||||||
"@types/jest": ^28.1.5
|
"@types/jest": ^28.1.5
|
||||||
@@ -7201,8 +7217,9 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@standardnotes/services@workspace:packages/services"
|
resolution: "@standardnotes/services@workspace:packages/services"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@standardnotes/api": "workspace:^"
|
||||||
"@standardnotes/auth": ^3.19.4
|
"@standardnotes/auth": ^3.19.4
|
||||||
"@standardnotes/common": ^1.30.0
|
"@standardnotes/common": ^1.32.0
|
||||||
"@standardnotes/encryption": "workspace:^"
|
"@standardnotes/encryption": "workspace:^"
|
||||||
"@standardnotes/files": "workspace:^"
|
"@standardnotes/files": "workspace:^"
|
||||||
"@standardnotes/models": "workspace:^"
|
"@standardnotes/models": "workspace:^"
|
||||||
@@ -7212,6 +7229,7 @@ __metadata:
|
|||||||
"@types/jest": ^28.1.5
|
"@types/jest": ^28.1.5
|
||||||
"@typescript-eslint/eslint-plugin": ^5.30.0
|
"@typescript-eslint/eslint-plugin": ^5.30.0
|
||||||
"@typescript-eslint/parser": ^5.12.1
|
"@typescript-eslint/parser": ^5.12.1
|
||||||
|
eslint: ^8.23.1
|
||||||
eslint-plugin-prettier: "*"
|
eslint-plugin-prettier: "*"
|
||||||
jest: ^28.1.2
|
jest: ^28.1.2
|
||||||
reflect-metadata: ^0.1.13
|
reflect-metadata: ^0.1.13
|
||||||
@@ -7312,7 +7330,7 @@ __metadata:
|
|||||||
"@babel/core": "*"
|
"@babel/core": "*"
|
||||||
"@babel/preset-env": "*"
|
"@babel/preset-env": "*"
|
||||||
"@standardnotes/api": "workspace:*"
|
"@standardnotes/api": "workspace:*"
|
||||||
"@standardnotes/common": ^1.25.0
|
"@standardnotes/common": ^1.32.0
|
||||||
"@standardnotes/domain-events": ^2.39.0
|
"@standardnotes/domain-events": ^2.39.0
|
||||||
"@standardnotes/encryption": "workspace:*"
|
"@standardnotes/encryption": "workspace:*"
|
||||||
"@standardnotes/features": "workspace:*"
|
"@standardnotes/features": "workspace:*"
|
||||||
@@ -7482,7 +7500,7 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@standardnotes/ui-services@workspace:packages/ui-services"
|
resolution: "@standardnotes/ui-services@workspace:packages/ui-services"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/common": ^1.30.0
|
"@standardnotes/common": ^1.32.0
|
||||||
"@standardnotes/filepicker": "workspace:^"
|
"@standardnotes/filepicker": "workspace:^"
|
||||||
"@standardnotes/services": "workspace:^"
|
"@standardnotes/services": "workspace:^"
|
||||||
"@standardnotes/styles": "workspace:^"
|
"@standardnotes/styles": "workspace:^"
|
||||||
@@ -7501,7 +7519,7 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@standardnotes/utils@workspace:packages/utils"
|
resolution: "@standardnotes/utils@workspace:packages/utils"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/common": ^1.23.1
|
"@standardnotes/common": ^1.32.0
|
||||||
"@types/dompurify": ^2.3.3
|
"@types/dompurify": ^2.3.3
|
||||||
"@types/jest": ^28.1.5
|
"@types/jest": ^28.1.5
|
||||||
"@types/jsdom": ^16.2.14
|
"@types/jsdom": ^16.2.14
|
||||||
@@ -18100,6 +18118,55 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"eslint@npm:^8.23.1":
|
||||||
|
version: 8.23.1
|
||||||
|
resolution: "eslint@npm:8.23.1"
|
||||||
|
dependencies:
|
||||||
|
"@eslint/eslintrc": ^1.3.2
|
||||||
|
"@humanwhocodes/config-array": ^0.10.4
|
||||||
|
"@humanwhocodes/gitignore-to-minimatch": ^1.0.2
|
||||||
|
"@humanwhocodes/module-importer": ^1.0.1
|
||||||
|
ajv: ^6.10.0
|
||||||
|
chalk: ^4.0.0
|
||||||
|
cross-spawn: ^7.0.2
|
||||||
|
debug: ^4.3.2
|
||||||
|
doctrine: ^3.0.0
|
||||||
|
escape-string-regexp: ^4.0.0
|
||||||
|
eslint-scope: ^7.1.1
|
||||||
|
eslint-utils: ^3.0.0
|
||||||
|
eslint-visitor-keys: ^3.3.0
|
||||||
|
espree: ^9.4.0
|
||||||
|
esquery: ^1.4.0
|
||||||
|
esutils: ^2.0.2
|
||||||
|
fast-deep-equal: ^3.1.3
|
||||||
|
file-entry-cache: ^6.0.1
|
||||||
|
find-up: ^5.0.0
|
||||||
|
glob-parent: ^6.0.1
|
||||||
|
globals: ^13.15.0
|
||||||
|
globby: ^11.1.0
|
||||||
|
grapheme-splitter: ^1.0.4
|
||||||
|
ignore: ^5.2.0
|
||||||
|
import-fresh: ^3.0.0
|
||||||
|
imurmurhash: ^0.1.4
|
||||||
|
is-glob: ^4.0.0
|
||||||
|
js-sdsl: ^4.1.4
|
||||||
|
js-yaml: ^4.1.0
|
||||||
|
json-stable-stringify-without-jsonify: ^1.0.1
|
||||||
|
levn: ^0.4.1
|
||||||
|
lodash.merge: ^4.6.2
|
||||||
|
minimatch: ^3.1.2
|
||||||
|
natural-compare: ^1.4.0
|
||||||
|
optionator: ^0.9.1
|
||||||
|
regexpp: ^3.2.0
|
||||||
|
strip-ansi: ^6.0.1
|
||||||
|
strip-json-comments: ^3.1.0
|
||||||
|
text-table: ^0.2.0
|
||||||
|
bin:
|
||||||
|
eslint: bin/eslint.js
|
||||||
|
checksum: a727e15492786a03b438bcf021db49f715680679846a7b8d79b98ad34576f2a570404ffe882d3c3e26f6359bff7277ef11fae5614bfe8629adb653f20d018c71
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"espree@npm:^7.3.0, espree@npm:^7.3.1":
|
"espree@npm:^7.3.0, espree@npm:^7.3.1":
|
||||||
version: 7.3.1
|
version: 7.3.1
|
||||||
resolution: "espree@npm:7.3.1"
|
resolution: "espree@npm:7.3.1"
|
||||||
@@ -24054,6 +24121,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"js-sdsl@npm:^4.1.4":
|
||||||
|
version: 4.1.4
|
||||||
|
resolution: "js-sdsl@npm:4.1.4"
|
||||||
|
checksum: 1977cea4ab18e0e03e28bdf0371d8b443fad65ca0988e0faa216406faf6bb943714fe8f7cc7a5bfe5f35ba3d94ddae399f4d10200f547f2c3320688b0670d726
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"js-string-escape@npm:^1.0.1":
|
"js-string-escape@npm:^1.0.1":
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
resolution: "js-string-escape@npm:1.0.1"
|
resolution: "js-string-escape@npm:1.0.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user