Compare commits

...
Author SHA1 Message Date
StandardNotes CI a0bc6153d6 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].6
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].5
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].7
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected]
2023-06-30 14:51:02 +00:00
Aman Harwara 89849c9f90 fix: Fixed issue where clicking in file dialog context menu closed the dialog 2023-06-30 19:51:08 +05:30
Mo b032eb9c9b internal: incomplete vault systems behind feature flag (#2340) 2023-06-30 09:01:56 -05:00
StandardNotes CI d16e401bb9 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].6
 - @standardnotes/[email protected].6
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected].9
2023-06-29 12:58:00 +00:00
Aman Harwara 476c5b4bdb chore: remove Labs status from Super 2023-06-29 17:57:07 +05:30
Aman Harwara 69de0e448f fix: Fixed issue where Conflicts view is shown but the list is empty 2023-06-29 17:54:38 +05:30
StandardNotes CI efe069db06 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].8
2023-06-27 20:39:44 +00:00
Aman Harwara edd3232c77 chore: update spreadsheets 2023-06-28 01:39:29 +05:30
StandardNotes CI 9ca0604352 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].5
 - @standardnotes/[email protected].5
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].7
2023-06-27 17:09:34 +00:00
Aman Harwara d3378a704a refactor: fix conflicts view when conflicted copies are already in trash (#2339) 2023-06-27 22:08:46 +05:30
StandardNotes CI f858f31492 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].6
2023-06-26 15:24:21 +00:00
Aman Harwara dffeb7e710 chore: fix signin menu closing on incorrect mfa 2023-06-26 19:56:00 +05:30
Aman Harwara c378288d6e chore: fix ios height issue 2023-06-26 19:37:49 +05:30
StandardNotes CI 65a09b77d3 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].5
2023-06-26 11:19:38 +00:00
Aman Harwara 24d159f6d8 chore: remove unused code 2023-06-26 16:20:03 +05:30
Aman Harwara 59fbf6f4c3 refactor: readonly note content 2023-06-26 16:12:35 +05:30
StandardNotes CI 28a52cb998 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
2023-06-26 10:12:21 +00:00
Mo 7f5041c4a8 chore: check for external request 2023-06-26 04:40:46 -05:00
StandardNotes CI 4b93dc35a8 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
2023-06-25 20:42:27 +00:00
Mo bb804fff45 fix: fixes issue where a renewed session would in some cases would not save to disk, causing a reauthentication prompt to occur 2023-06-25 15:12:22 -05:00
682 changed files with 20952 additions and 5039 deletions
-1
View File
@@ -26,7 +26,6 @@
"build:snjs": "yarn workspaces foreach -p --topological-dev --verbose -R --from @standardnotes/snjs run build",
"build:services": "yarn workspaces foreach -pt --topological-dev --verbose -R --from @standardnotes/services run build",
"build:api": "yarn workspaces foreach -pt --topological-dev --verbose -R --from @standardnotes/api run build",
"start:server:web": "lerna run start --scope=@standardnotes/web",
"e2e": "lerna run start:test-server --scope=@standardnotes/snjs",
"reset": "find . -type dir -name node_modules | xargs rm -rf && rm -rf yarn.lock && yarn install",
"release:prod": "lerna version --conventional-commits --yes -m \"chore(release): publish\"",
+22
View File
@@ -3,6 +3,28 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.26.18](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-30)
**Note:** Version bump only for package @standardnotes/api
## [1.26.17](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-29)
**Note:** Version bump only for package @standardnotes/api
## [1.26.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-27)
**Note:** Version bump only for package @standardnotes/api
## [1.26.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-26)
**Note:** Version bump only for package @standardnotes/api
## [1.26.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-25)
### Bug Fixes
* fixes issue where a renewed session would in some cases would not save to disk, causing a reauthentication prompt to occur ([bb804ff](https://github.com/standardnotes/app/commit/bb804fff45328eef3c66ec3a48dc000c21e37020))
## [1.26.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-25)
**Note:** Version bump only for package @standardnotes/api
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api",
"version": "1.26.13",
"version": "1.26.18",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -36,7 +36,7 @@
"typescript": "*"
},
"dependencies": {
"@standardnotes/common": "^1.46.6",
"@standardnotes/common": "^1.48.3",
"@standardnotes/domain-core": "^1.12.0",
"@standardnotes/encryption": "workspace:*",
"@standardnotes/models": "workspace:*",
@@ -1,14 +1,14 @@
import { ErrorMessage } from '../../Error/ErrorMessage'
import { ApiCallError } from '../../Error/ApiCallError'
import { ApiVersion } from '../../Api/ApiVersion'
import { ApiEndpointParam } from '../../Request/ApiEndpointParam'
import { SubscriptionServerInterface } from '../../Server/Subscription/SubscriptionServerInterface'
import { AppleIAPConfirmResponseBody } from './../../Response/Subscription/AppleIAPConfirmResponseBody'
import { SubscriptionInviteAcceptResponseBody } from '../../Response/Subscription/SubscriptionInviteAcceptResponseBody'
import { SubscriptionInviteCancelResponseBody } from '../../Response/Subscription/SubscriptionInviteCancelResponseBody'
import { SubscriptionInviteListResponseBody } from '../../Response/Subscription/SubscriptionInviteListResponseBody'
import { SubscriptionInviteResponseBody } from '../../Response/Subscription/SubscriptionInviteResponseBody'
import { HttpResponse } from '@standardnotes/responses'
import { HttpResponse, ApiEndpointParam } from '@standardnotes/responses'
import { SubscriptionApiServiceInterface } from './SubscriptionApiServiceInterface'
import { SubscriptionApiOperations } from './SubscriptionApiOperations'
@@ -2,4 +2,5 @@ export enum UserApiOperations {
Registering,
SubmittingRequest,
DeletingAccount,
UpdatingUser,
}
@@ -5,8 +5,7 @@ import { ErrorMessage } from '../../Error/ErrorMessage'
import { ApiCallError } from '../../Error/ApiCallError'
import { UserServerInterface } from '../../Server/User/UserServerInterface'
import { ApiVersion } from '../../Api/ApiVersion'
import { ApiEndpointParam } from '../../Request/ApiEndpointParam'
import { HttpResponse } from '@standardnotes/responses'
import { HttpResponse, ApiEndpointParam } from '@standardnotes/responses'
import { UserDeletionResponseBody } from '../../Response/User/UserDeletionResponseBody'
import { UserRegistrationResponseBody } from '../../Response/User/UserRegistrationResponseBody'
@@ -15,6 +14,7 @@ import { UserRequestServerInterface } from '../../Server/UserRequest/UserRequest
import { UserApiOperations } from './UserApiOperations'
import { UserApiServiceInterface } from './UserApiServiceInterface'
import { UserUpdateResponse } from '../../Response/User/UserUpdateResponse'
export class UserApiService implements UserApiServiceInterface {
private operationsInProgress: Map<UserApiOperations, boolean>
@@ -35,7 +35,7 @@ export class UserApiService implements UserApiServiceInterface {
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericRegistrationFail)
throw new ApiCallError(ErrorMessage.GenericFail)
}
}
@@ -84,6 +84,23 @@ export class UserApiService implements UserApiServiceInterface {
}
}
async updateUser(updateDTO: { userUuid: string }): Promise<HttpResponse<UserUpdateResponse>> {
this.lockOperation(UserApiOperations.UpdatingUser)
try {
const response = await this.userServer.update({
[ApiEndpointParam.ApiVersion]: ApiVersion.v0,
user_uuid: updateDTO.userUuid,
})
this.unlockOperation(UserApiOperations.UpdatingUser)
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
}
}
private lockOperation(operation: UserApiOperations): void {
if (this.operationsInProgress.get(operation)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
@@ -5,6 +5,7 @@ import { HttpResponse } from '@standardnotes/responses'
import { UserDeletionResponseBody } from '../../Response/User/UserDeletionResponseBody'
import { UserRegistrationResponseBody } from '../../Response/User/UserRegistrationResponseBody'
import { UserRequestResponseBody } from '../../Response/UserRequest/UserRequestResponseBody'
import { UserUpdateResponse } from '../../Response/User/UserUpdateResponse'
export interface UserApiServiceInterface {
register(registerDTO: {
@@ -13,9 +14,12 @@ export interface UserApiServiceInterface {
keyParams: RootKeyParamsInterface
ephemeral: boolean
}): Promise<HttpResponse<UserRegistrationResponseBody>>
updateUser(updateDTO: { userUuid: string }): Promise<HttpResponse<UserUpdateResponse>>
submitUserRequest(dto: {
userUuid: string
requestType: UserRequestType
}): Promise<HttpResponse<UserRequestResponseBody>>
deleteAccount(userUuid: string): Promise<HttpResponse<UserDeletionResponseBody>>
}
+29 -7
View File
@@ -53,7 +53,15 @@ export class HttpService implements HttpServiceInterface {
this.host = host
}
getHost(): string {
return this.host
}
async get<T>(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse<T>> {
if (!this.host) {
throw new Error('Attempting to make network request before host is set')
}
return this.runHttp({
url: joinPaths(this.host, path),
params,
@@ -62,7 +70,20 @@ export class HttpService implements HttpServiceInterface {
})
}
async getExternal<T>(url: string, params?: HttpRequestParams): Promise<HttpResponse<T>> {
return this.runHttp({
url,
params,
verb: HttpVerb.Get,
external: true,
})
}
async post<T>(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse<T>> {
if (!this.host) {
throw new Error('Attempting to make network request before host is set')
}
return this.runHttp({
url: joinPaths(this.host, path),
params,
@@ -99,7 +120,12 @@ export class HttpService implements HttpServiceInterface {
}
async runHttp<T>(httpRequest: HttpRequest): Promise<HttpResponse<T>> {
if (this.inProgressRefreshSessionPromise) {
if (this.__latencySimulatorMs) {
await sleep(this.__latencySimulatorMs, true)
}
const isRefreshRequest = httpRequest.url === joinPaths(this.host, Paths.v1.refreshSession)
if (this.inProgressRefreshSessionPromise && !isRefreshRequest) {
await this.inProgressRefreshSessionPromise
httpRequest.authentication = this.session?.accessToken.value
@@ -107,17 +133,13 @@ export class HttpService implements HttpServiceInterface {
const request = this.createXmlRequest(httpRequest)
if (this.__latencySimulatorMs) {
await sleep(this.__latencySimulatorMs, true)
}
const response = await this.runRequest<T>(request, this.createRequestBody(httpRequest))
if (response.meta) {
if (response.meta && !httpRequest.external) {
this.updateMetaCallback?.(response.meta)
}
if (response.status === HttpStatusCode.ExpiredAccessToken) {
if (response.status === HttpStatusCode.ExpiredAccessToken && !isRefreshRequest && !httpRequest.external) {
if (this.inProgressRefreshSessionPromise) {
await this.inProgressRefreshSessionPromise
} else {
@@ -3,8 +3,10 @@ import { HttpRequest, HttpRequestParams, HttpResponse, HttpResponseMeta } from '
export interface HttpServiceInterface {
setHost(host: string): void
getHost(): string
setSession(session: Session): void
get<T>(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse<T>>
getExternal<T>(url: string, params?: HttpRequestParams): Promise<HttpResponse<T>>
post<T>(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse<T>>
put<T>(path: string, params?: HttpRequestParams, authentication?: string): Promise<HttpResponse<T>>
patch<T>(path: string, params: HttpRequestParams, authentication?: string): Promise<HttpResponse<T>>
@@ -1,7 +0,0 @@
export enum ApiEndpointParam {
LastSyncToken = 'sync_token',
PaginationToken = 'cursor_token',
SyncDlLimit = 'limit',
SyncPayloads = 'items',
ApiVersion = 'api',
}
@@ -0,0 +1,5 @@
export type CreateAsymmetricMessageParams = {
recipientUuid: string
encryptedMessage: string
replaceabilityIdentifier?: string
}
@@ -0,0 +1,3 @@
export type DeleteAsymmetricMessageRequestParams = {
messageUuid: string
}
@@ -0,0 +1,2 @@
// eslint-disable-next-line @typescript-eslint/ban-types
export type GetOutboundAsymmetricMessagesRequestParams = {}
@@ -0,0 +1,2 @@
// eslint-disable-next-line @typescript-eslint/ban-types
export type GetUserAsymmetricMessagesRequestParams = {}
@@ -0,0 +1,4 @@
export type UpdateAsymmetricMessageParams = {
messageUuid: string
encryptedMessage: string
}
@@ -0,0 +1,12 @@
import { ValetTokenOperation } from '@standardnotes/responses'
import { SharedVaultMoveType } from './SharedVaultMoveType'
export type CreateSharedVaultValetTokenParams = {
sharedVaultUuid: string
fileUuid?: string
remoteIdentifier: string
operation: ValetTokenOperation
unencryptedFileSize?: number
moveOperationType?: SharedVaultMoveType
sharedVaultToSharedVaultMoveTargetUuid?: string
}
@@ -0,0 +1 @@
export type SharedVaultMoveType = 'shared-vault-to-user' | 'user-to-shared-vault' | 'shared-vault-to-shared-vault'
@@ -0,0 +1,4 @@
export type AcceptInviteRequestParams = {
sharedVaultUuid: string
inviteUuid: string
}
@@ -0,0 +1,8 @@
import { SharedVaultPermission } from '@standardnotes/responses'
export type CreateSharedVaultInviteParams = {
sharedVaultUuid: string
recipientUuid: string
encryptedMessage: string
permissions: SharedVaultPermission
}
@@ -0,0 +1,4 @@
export type DeclineInviteRequestParams = {
sharedVaultUuid: string
inviteUuid: string
}
@@ -0,0 +1,3 @@
export type DeleteAllSharedVaultInvitesRequestParams = {
sharedVaultUuid: string
}
@@ -0,0 +1,4 @@
export type DeleteInviteRequestParams = {
sharedVaultUuid: string
inviteUuid: string
}
@@ -0,0 +1,2 @@
// eslint-disable-next-line @typescript-eslint/ban-types
export type GetOutboundUserInvitesRequestParams = {}
@@ -0,0 +1,3 @@
export type GetSharedVaultInvitesRequestParams = {
sharedVaultUuid: string
}
@@ -0,0 +1,2 @@
// eslint-disable-next-line @typescript-eslint/ban-types
export type GetUserInvitesRequestParams = {}
@@ -0,0 +1,8 @@
import { SharedVaultPermission } from '@standardnotes/responses'
export type UpdateSharedVaultInviteParams = {
sharedVaultUuid: string
inviteUuid: string
encryptedMessage: string
permissions?: SharedVaultPermission
}
@@ -0,0 +1,4 @@
export type DeleteSharedVaultUserRequestParams = {
sharedVaultUuid: string
userUuid: string
}
@@ -0,0 +1,3 @@
export type GetSharedVaultUsersRequestParams = {
sharedVaultUuid: string
}
@@ -1,4 +1,4 @@
import { ApiEndpointParam } from '../ApiEndpointParam'
import { ApiEndpointParam } from '@standardnotes/responses'
import { ApiVersion } from '../../Api/ApiVersion'
export type SubscriptionInviteCancelRequestParams = {
@@ -1,4 +1,4 @@
import { ApiEndpointParam } from '../ApiEndpointParam'
import { ApiEndpointParam } from '@standardnotes/responses'
import { ApiVersion } from '../../Api/ApiVersion'
export type SubscriptionInviteDeclineRequestParams = {
@@ -1,4 +1,4 @@
import { ApiEndpointParam } from '../ApiEndpointParam'
import { ApiEndpointParam } from '@standardnotes/responses'
import { ApiVersion } from '../../Api/ApiVersion'
export type SubscriptionInviteListRequestParams = {
@@ -1,4 +1,4 @@
import { ApiEndpointParam } from '../ApiEndpointParam'
import { ApiEndpointParam } from '@standardnotes/responses'
import { ApiVersion } from '../../Api/ApiVersion'
export type SubscriptionInviteRequestParams = {
@@ -1,13 +1,11 @@
import { AnyKeyParamsContent } from '@standardnotes/common'
import { ApiEndpointParam } from '../ApiEndpointParam'
import { ApiEndpointParam } from '@standardnotes/responses'
import { ApiVersion } from '../../Api/ApiVersion'
export type UserRegistrationRequestParams = AnyKeyParamsContent & {
[ApiEndpointParam.ApiVersion]: ApiVersion.v0
[additionalParam: string]: unknown
password: string
email: string
ephemeral: boolean
[additionalParam: string]: unknown
pkcPublicKey?: string
pkcEncryptedPrivateKey?: string
}
@@ -0,0 +1,7 @@
import { ApiEndpointParam } from '@standardnotes/responses'
import { ApiVersion } from '../../Api/ApiVersion'
export type UserUpdateRequestParams = {
[ApiEndpointParam.ApiVersion]: ApiVersion.v0
user_uuid: string
}
+1 -1
View File
@@ -1,4 +1,3 @@
export * from './ApiEndpointParam'
export * from './Authenticator/DeleteAuthenticatorRequestParams'
export * from './Authenticator/GenerateAuthenticatorAuthenticationOptionsRequestParams'
export * from './Authenticator/ListAuthenticatorsRequestParams'
@@ -17,3 +16,4 @@ export * from './Subscription/SubscriptionInviteRequestParams'
export * from './User/UserRegistrationRequestParams'
export * from './UserRequest/UserRequestRequestParams'
export * from './WebSocket/WebSocketConnectionTokenRequestParams'
export * from './SharedVault/SharedVaultMoveType'
@@ -0,0 +1,5 @@
import { AsymmetricMessageServerHash } from '@standardnotes/responses'
export type CreateAsymmetricMessageResponse = {
message: AsymmetricMessageServerHash
}
@@ -0,0 +1,3 @@
export type DeleteAsymmetricMessageResponse = {
success: boolean
}
@@ -0,0 +1,5 @@
import { AsymmetricMessageServerHash } from '@standardnotes/responses'
export type GetOutboundAsymmetricMessagesResponse = {
messages: AsymmetricMessageServerHash[]
}
@@ -0,0 +1,5 @@
import { AsymmetricMessageServerHash } from '@standardnotes/responses'
export type GetUserAsymmetricMessagesResponse = {
messages: AsymmetricMessageServerHash[]
}
@@ -0,0 +1,5 @@
import { AsymmetricMessageServerHash } from '@standardnotes/responses'
export type UpdateAsymmetricMessageResponse = {
message: AsymmetricMessageServerHash
}
@@ -7,6 +7,9 @@ export interface GetRevisionResponseBody {
items_key_id: string | null
enc_item_key: string | null
auth_hash: string | null
user_uuid: string
key_system_identifier: string | null
shared_vault_uuid: string | null
created_at: string
updated_at: string
}
@@ -0,0 +1,6 @@
import { SharedVaultUserServerHash, SharedVaultServerHash } from '@standardnotes/responses'
export type CreateSharedVaultResponse = {
sharedVault: SharedVaultServerHash
sharedVaultUser: SharedVaultUserServerHash
}
@@ -0,0 +1,3 @@
export type CreateSharedVaultValetTokenResponse = {
valetToken: string
}
@@ -0,0 +1,5 @@
import { SharedVaultServerHash } from '@standardnotes/responses'
export type GetSharedVaultsResponse = {
sharedVaults: SharedVaultServerHash[]
}
@@ -0,0 +1,3 @@
export type AcceptInviteResponse = {
success: boolean
}
@@ -0,0 +1,5 @@
import { SharedVaultInviteServerHash } from '@standardnotes/responses'
export type CreateSharedVaultInviteResponse = {
invite: SharedVaultInviteServerHash
}
@@ -0,0 +1,3 @@
export type DeclineInviteResponse = {
success: boolean
}
@@ -0,0 +1,3 @@
export type DeleteAllSharedVaultInvitesResponse = {
success: boolean
}
@@ -0,0 +1,3 @@
export type DeleteInviteResponse = {
success: boolean
}
@@ -0,0 +1,5 @@
import { SharedVaultInviteServerHash } from '@standardnotes/responses'
export type GetOutboundUserInvitesResponse = {
invites: SharedVaultInviteServerHash[]
}
@@ -0,0 +1,5 @@
import { SharedVaultInviteServerHash } from '@standardnotes/responses'
export type GetSharedVaultInvitesResponse = {
invites: SharedVaultInviteServerHash[]
}
@@ -0,0 +1,5 @@
import { SharedVaultInviteServerHash } from '@standardnotes/responses'
export type GetUserInvitesResponse = {
invites: SharedVaultInviteServerHash[]
}
@@ -0,0 +1,5 @@
import { SharedVaultInviteServerHash } from '@standardnotes/responses'
export type UpdateSharedVaultInviteResponse = {
invite: SharedVaultInviteServerHash
}
@@ -0,0 +1,3 @@
export type DeleteSharedVaultUserResponse = {
success: boolean
}
@@ -0,0 +1,5 @@
import { SharedVaultUserServerHash } from '@standardnotes/responses'
export type GetSharedVaultUsersResponse = {
users: SharedVaultUserServerHash[]
}
@@ -0,0 +1,6 @@
export type UserUpdateResponse = {
user: {
uuid: string
email: string
}
}
@@ -16,7 +16,9 @@ export * from './Subscription/SubscriptionInviteCancelResponseBody'
export * from './Subscription/SubscriptionInviteDeclineResponseBody'
export * from './Subscription/SubscriptionInviteListResponseBody'
export * from './Subscription/SubscriptionInviteResponseBody'
export * from './User/UserDeletionResponseBody'
export * from './User/UserRegistrationResponseBody'
export * from './UserRequest/UserRequestResponseBody'
export * from './WebSocket/WebSocketConnectionTokenResponseBody'
@@ -0,0 +1,41 @@
import { HttpResponse } from '@standardnotes/responses'
import { HttpServiceInterface } from '../../Http'
import { CreateAsymmetricMessageParams } from '../../Request/AsymmetricMessage/CreateAsymmetricMessageParams'
import { CreateAsymmetricMessageResponse } from '../../Response/AsymmetricMessage/CreateAsymmetricMessageResponse'
import { AsymmetricMessagesPaths } from './Paths'
import { GetUserAsymmetricMessagesResponse } from '../../Response/AsymmetricMessage/GetUserAsymmetricMessagesResponse'
import { AsymmetricMessageServerInterface } from './AsymmetricMessageServerInterface'
import { DeleteAsymmetricMessageRequestParams } from '../../Request/AsymmetricMessage/DeleteAsymmetricMessageRequestParams'
import { DeleteAsymmetricMessageResponse } from '../../Response/AsymmetricMessage/DeleteAsymmetricMessageResponse'
export class AsymmetricMessageServer implements AsymmetricMessageServerInterface {
constructor(private httpService: HttpServiceInterface) {}
createMessage(params: CreateAsymmetricMessageParams): Promise<HttpResponse<CreateAsymmetricMessageResponse>> {
return this.httpService.post(AsymmetricMessagesPaths.createMessage, {
recipient_uuid: params.recipientUuid,
encrypted_message: params.encryptedMessage,
replaceability_identifier: params.replaceabilityIdentifier,
})
}
getInboundUserMessages(): Promise<HttpResponse<GetUserAsymmetricMessagesResponse>> {
return this.httpService.get(AsymmetricMessagesPaths.getInboundUserMessages())
}
getOutboundUserMessages(): Promise<HttpResponse<GetUserAsymmetricMessagesResponse>> {
return this.httpService.get(AsymmetricMessagesPaths.getOutboundUserMessages())
}
getMessages(): Promise<HttpResponse<GetUserAsymmetricMessagesResponse>> {
return this.httpService.get(AsymmetricMessagesPaths.getMessages)
}
deleteMessage(params: DeleteAsymmetricMessageRequestParams): Promise<HttpResponse<DeleteAsymmetricMessageResponse>> {
return this.httpService.delete(AsymmetricMessagesPaths.deleteMessage(params.messageUuid))
}
deleteAllInboundMessages(): Promise<HttpResponse<{ success: boolean }>> {
return this.httpService.delete(AsymmetricMessagesPaths.deleteAllInboundMessages)
}
}
@@ -0,0 +1,17 @@
import { HttpResponse } from '@standardnotes/responses'
import { CreateAsymmetricMessageParams } from '../../Request/AsymmetricMessage/CreateAsymmetricMessageParams'
import { CreateAsymmetricMessageResponse } from '../../Response/AsymmetricMessage/CreateAsymmetricMessageResponse'
import { GetUserAsymmetricMessagesResponse } from '../../Response/AsymmetricMessage/GetUserAsymmetricMessagesResponse'
import { DeleteAsymmetricMessageRequestParams } from '../../Request/AsymmetricMessage/DeleteAsymmetricMessageRequestParams'
import { DeleteAsymmetricMessageResponse } from '../../Response/AsymmetricMessage/DeleteAsymmetricMessageResponse'
export interface AsymmetricMessageServerInterface {
createMessage(params: CreateAsymmetricMessageParams): Promise<HttpResponse<CreateAsymmetricMessageResponse>>
getInboundUserMessages(): Promise<HttpResponse<GetUserAsymmetricMessagesResponse>>
getOutboundUserMessages(): Promise<HttpResponse<GetUserAsymmetricMessagesResponse>>
getMessages(): Promise<HttpResponse<GetUserAsymmetricMessagesResponse>>
deleteMessage(params: DeleteAsymmetricMessageRequestParams): Promise<HttpResponse<DeleteAsymmetricMessageResponse>>
deleteAllInboundMessages(): Promise<HttpResponse<{ success: boolean }>>
}
@@ -0,0 +1,9 @@
export const AsymmetricMessagesPaths = {
createMessage: '/v1/asymmetric-messages',
getMessages: '/v1/asymmetric-messages',
updateMessage: (messageUuid: string) => `/v1/asymmetric-messages/${messageUuid}`,
getInboundUserMessages: () => '/v1/asymmetric-messages',
getOutboundUserMessages: () => '/v1/asymmetric-messages/outbound',
deleteMessage: (messageUuid: string) => `/v1/asymmetric-messages/${messageUuid}`,
deleteAllInboundMessages: '/v1/asymmetric-messages/inbound',
}
@@ -0,0 +1,7 @@
export const SharedVaultsPaths = {
getSharedVaults: '/v1/shared-vaults',
createSharedVault: '/v1/shared-vaults',
deleteSharedVault: (sharedVaultUuid: string) => `/v1/shared-vaults/${sharedVaultUuid}`,
updateSharedVault: (sharedVaultUuid: string) => `/v1/shared-vaults/${sharedVaultUuid}`,
createSharedVaultFileValetToken: (sharedVaultUuid: string) => `/v1/shared-vaults/${sharedVaultUuid}/valet-tokens`,
}
@@ -0,0 +1,37 @@
import { HttpResponse } from '@standardnotes/responses'
import { HttpServiceInterface } from '../../Http'
import { SharedVaultServerInterface } from './SharedVaultServerInterface'
import { SharedVaultsPaths } from './Paths'
import { CreateSharedVaultResponse } from '../../Response/SharedVault/CreateSharedVaultResponse'
import { GetSharedVaultsResponse } from '../../Response/SharedVault/GetSharedVaultsResponse'
import { CreateSharedVaultValetTokenResponse } from '../../Response/SharedVault/CreateSharedVaultValetTokenResponse'
import { CreateSharedVaultValetTokenParams } from '../../Request/SharedVault/CreateSharedVaultValetTokenParams'
export class SharedVaultServer implements SharedVaultServerInterface {
constructor(private httpService: HttpServiceInterface) {}
getSharedVaults(): Promise<HttpResponse<GetSharedVaultsResponse>> {
return this.httpService.get(SharedVaultsPaths.getSharedVaults)
}
createSharedVault(): Promise<HttpResponse<CreateSharedVaultResponse>> {
return this.httpService.post(SharedVaultsPaths.createSharedVault)
}
deleteSharedVault(params: { sharedVaultUuid: string }): Promise<HttpResponse<boolean>> {
return this.httpService.delete(SharedVaultsPaths.deleteSharedVault(params.sharedVaultUuid))
}
createSharedVaultFileValetToken(
params: CreateSharedVaultValetTokenParams,
): Promise<HttpResponse<CreateSharedVaultValetTokenResponse>> {
return this.httpService.post(SharedVaultsPaths.createSharedVaultFileValetToken(params.sharedVaultUuid), {
file_uuid: params.fileUuid,
remote_identifier: params.remoteIdentifier,
operation: params.operation,
unencrypted_file_size: params.unencryptedFileSize,
move_operation_type: params.moveOperationType,
shared_vault_to_shared_vault_move_target_uuid: params.sharedVaultToSharedVaultMoveTargetUuid,
})
}
}
@@ -0,0 +1,17 @@
import { HttpResponse } from '@standardnotes/responses'
import { CreateSharedVaultResponse } from '../../Response/SharedVault/CreateSharedVaultResponse'
import { GetSharedVaultsResponse } from '../../Response/SharedVault/GetSharedVaultsResponse'
import { CreateSharedVaultValetTokenResponse } from '../../Response/SharedVault/CreateSharedVaultValetTokenResponse'
import { CreateSharedVaultValetTokenParams } from '../../Request/SharedVault/CreateSharedVaultValetTokenParams'
export interface SharedVaultServerInterface {
getSharedVaults(): Promise<HttpResponse<GetSharedVaultsResponse>>
createSharedVault(): Promise<HttpResponse<CreateSharedVaultResponse>>
deleteSharedVault(params: { sharedVaultUuid: string }): Promise<HttpResponse<boolean>>
createSharedVaultFileValetToken(
params: CreateSharedVaultValetTokenParams,
): Promise<HttpResponse<CreateSharedVaultValetTokenResponse>>
}
@@ -0,0 +1,16 @@
export const SharedVaultInvitesPaths = {
createInvite: (sharedVaultUuid: string) => `/v1/shared-vaults/${sharedVaultUuid}/invites`,
updateInvite: (sharedVaultUuid: string, inviteUuid: string) =>
`/v1/shared-vaults/${sharedVaultUuid}/invites/${inviteUuid}`,
acceptInvite: (sharedVaultUuid: string, inviteUuid: string) =>
`/v1/shared-vaults/${sharedVaultUuid}/invites/${inviteUuid}/accept`,
declineInvite: (sharedVaultUuid: string, inviteUuid: string) =>
`/v1/shared-vaults/${sharedVaultUuid}/invites/${inviteUuid}/decline`,
getInboundUserInvites: () => '/v1/shared-vaults/invites',
getOutboundUserInvites: () => '/v1/shared-vaults/invites/outbound',
getSharedVaultInvites: (sharedVaultUuid: string) => `/v1/shared-vaults/${sharedVaultUuid}/invites`,
deleteInvite: (sharedVaultUuid: string, inviteUuid: string) =>
`/v1/shared-vaults/${sharedVaultUuid}/invites/${inviteUuid}`,
deleteAllSharedVaultInvites: (sharedVaultUuid: string) => `/v1/shared-vaults/${sharedVaultUuid}/invites`,
deleteAllInboundInvites: '/v1/shared-vaults/invites/inbound',
}
@@ -0,0 +1,75 @@
import { HttpResponse } from '@standardnotes/responses'
import { HttpServiceInterface } from '../../Http'
import { AcceptInviteRequestParams } from '../../Request/SharedVaultInvites/AcceptInviteRequestParams'
import { AcceptInviteResponse } from '../../Response/SharedVaultInvites/AcceptInviteResponse'
import { CreateSharedVaultInviteParams } from '../../Request/SharedVaultInvites/CreateSharedVaultInviteParams'
import { CreateSharedVaultInviteResponse } from '../../Response/SharedVaultInvites/CreateSharedVaultInviteResponse'
import { DeclineInviteRequestParams } from '../../Request/SharedVaultInvites/DeclineInviteRequestParams'
import { DeclineInviteResponse } from '../../Response/SharedVaultInvites/DeclineInviteResponse'
import { DeleteInviteRequestParams } from '../../Request/SharedVaultInvites/DeleteInviteRequestParams'
import { DeleteInviteResponse } from '../../Response/SharedVaultInvites/DeleteInviteResponse'
import { GetSharedVaultInvitesRequestParams } from '../../Request/SharedVaultInvites/GetSharedVaultInvitesRequestParams'
import { GetSharedVaultInvitesResponse } from '../../Response/SharedVaultInvites/GetSharedVaultInvitesResponse'
import { GetUserInvitesResponse } from '../../Response/SharedVaultInvites/GetUserInvitesResponse'
import { SharedVaultInvitesPaths } from './Paths'
import { SharedVaultInvitesServerInterface } from './SharedVaultInvitesServerInterface'
import { UpdateSharedVaultInviteParams } from '../../Request/SharedVaultInvites/UpdateSharedVaultInviteParams'
import { UpdateSharedVaultInviteResponse } from '../../Response/SharedVaultInvites/UpdateSharedVaultInviteResponse'
import { DeleteAllSharedVaultInvitesRequestParams } from '../../Request/SharedVaultInvites/DeleteAllSharedVaultInvitesRequestParams'
import { DeleteAllSharedVaultInvitesResponse } from '../../Response/SharedVaultInvites/DeleteAllSharedVaultInvitesResponse'
export class SharedVaultInvitesServer implements SharedVaultInvitesServerInterface {
constructor(private httpService: HttpServiceInterface) {}
createInvite(params: CreateSharedVaultInviteParams): Promise<HttpResponse<CreateSharedVaultInviteResponse>> {
return this.httpService.post(SharedVaultInvitesPaths.createInvite(params.sharedVaultUuid), {
recipient_uuid: params.recipientUuid,
encrypted_message: params.encryptedMessage,
permissions: params.permissions,
})
}
updateInvite(params: UpdateSharedVaultInviteParams): Promise<HttpResponse<UpdateSharedVaultInviteResponse>> {
return this.httpService.patch(SharedVaultInvitesPaths.updateInvite(params.sharedVaultUuid, params.inviteUuid), {
encrypted_message: params.encryptedMessage,
permissions: params.permissions,
})
}
acceptInvite(params: AcceptInviteRequestParams): Promise<HttpResponse<AcceptInviteResponse>> {
return this.httpService.post(SharedVaultInvitesPaths.acceptInvite(params.sharedVaultUuid, params.inviteUuid))
}
declineInvite(params: DeclineInviteRequestParams): Promise<HttpResponse<DeclineInviteResponse>> {
return this.httpService.post(SharedVaultInvitesPaths.declineInvite(params.sharedVaultUuid, params.inviteUuid))
}
getInboundUserInvites(): Promise<HttpResponse<GetUserInvitesResponse>> {
return this.httpService.get(SharedVaultInvitesPaths.getInboundUserInvites())
}
getOutboundUserInvites(): Promise<HttpResponse<GetUserInvitesResponse>> {
return this.httpService.get(SharedVaultInvitesPaths.getOutboundUserInvites())
}
getSharedVaultInvites(
params: GetSharedVaultInvitesRequestParams,
): Promise<HttpResponse<GetSharedVaultInvitesResponse>> {
return this.httpService.get(SharedVaultInvitesPaths.getSharedVaultInvites(params.sharedVaultUuid))
}
deleteInvite(params: DeleteInviteRequestParams): Promise<HttpResponse<DeleteInviteResponse>> {
return this.httpService.delete(SharedVaultInvitesPaths.deleteInvite(params.sharedVaultUuid, params.inviteUuid))
}
deleteAllSharedVaultInvites(
params: DeleteAllSharedVaultInvitesRequestParams,
): Promise<HttpResponse<DeleteAllSharedVaultInvitesResponse>> {
return this.httpService.delete(SharedVaultInvitesPaths.deleteAllSharedVaultInvites(params.sharedVaultUuid))
}
deleteAllInboundInvites(): Promise<HttpResponse<{ success: boolean }>> {
return this.httpService.delete(SharedVaultInvitesPaths.deleteAllInboundInvites)
}
}
@@ -0,0 +1,35 @@
import { HttpResponse } from '@standardnotes/responses'
import { AcceptInviteRequestParams } from '../../Request/SharedVaultInvites/AcceptInviteRequestParams'
import { AcceptInviteResponse } from '../../Response/SharedVaultInvites/AcceptInviteResponse'
import { CreateSharedVaultInviteParams } from '../../Request/SharedVaultInvites/CreateSharedVaultInviteParams'
import { CreateSharedVaultInviteResponse } from '../../Response/SharedVaultInvites/CreateSharedVaultInviteResponse'
import { DeclineInviteRequestParams } from '../../Request/SharedVaultInvites/DeclineInviteRequestParams'
import { DeclineInviteResponse } from '../../Response/SharedVaultInvites/DeclineInviteResponse'
import { DeleteInviteRequestParams } from '../../Request/SharedVaultInvites/DeleteInviteRequestParams'
import { DeleteInviteResponse } from '../../Response/SharedVaultInvites/DeleteInviteResponse'
import { GetSharedVaultInvitesRequestParams } from '../../Request/SharedVaultInvites/GetSharedVaultInvitesRequestParams'
import { GetSharedVaultInvitesResponse } from '../../Response/SharedVaultInvites/GetSharedVaultInvitesResponse'
import { GetUserInvitesResponse } from '../../Response/SharedVaultInvites/GetUserInvitesResponse'
import { UpdateSharedVaultInviteParams } from '../../Request/SharedVaultInvites/UpdateSharedVaultInviteParams'
import { UpdateSharedVaultInviteResponse } from '../../Response/SharedVaultInvites/UpdateSharedVaultInviteResponse'
import { DeleteAllSharedVaultInvitesRequestParams } from '../../Request/SharedVaultInvites/DeleteAllSharedVaultInvitesRequestParams'
import { DeleteAllSharedVaultInvitesResponse } from '../../Response/SharedVaultInvites/DeleteAllSharedVaultInvitesResponse'
export interface SharedVaultInvitesServerInterface {
createInvite(params: CreateSharedVaultInviteParams): Promise<HttpResponse<CreateSharedVaultInviteResponse>>
updateInvite(params: UpdateSharedVaultInviteParams): Promise<HttpResponse<UpdateSharedVaultInviteResponse>>
acceptInvite(params: AcceptInviteRequestParams): Promise<HttpResponse<AcceptInviteResponse>>
declineInvite(params: DeclineInviteRequestParams): Promise<HttpResponse<DeclineInviteResponse>>
getInboundUserInvites(): Promise<HttpResponse<GetUserInvitesResponse>>
getOutboundUserInvites(): Promise<HttpResponse<GetUserInvitesResponse>>
getSharedVaultInvites(
params: GetSharedVaultInvitesRequestParams,
): Promise<HttpResponse<GetSharedVaultInvitesResponse>>
deleteAllSharedVaultInvites(
params: DeleteAllSharedVaultInvitesRequestParams,
): Promise<HttpResponse<DeleteAllSharedVaultInvitesResponse>>
deleteInvite(params: DeleteInviteRequestParams): Promise<HttpResponse<DeleteInviteResponse>>
deleteAllInboundInvites(): Promise<HttpResponse<{ success: boolean }>>
}
@@ -0,0 +1,5 @@
export const SharedVaultUsersPaths = {
getSharedVaultUsers: (sharedVaultUuid: string) => `/v1/shared-vaults/${sharedVaultUuid}/users`,
deleteSharedVaultUser: (sharedVaultUuid: string, userUuid: string) =>
`/v1/shared-vaults/${sharedVaultUuid}/users/${userUuid}`,
}
@@ -0,0 +1,22 @@
import { HttpResponse } from '@standardnotes/responses'
import { HttpServiceInterface } from '../../Http'
import { GetSharedVaultUsersRequestParams } from '../../Request/SharedVaultUser/GetSharedVaultUsersRequestParams'
import { DeleteSharedVaultUserRequestParams } from '../../Request/SharedVaultUser/DeleteSharedVaultUserRequestParams'
import { DeleteSharedVaultUserResponse } from '../../Response/SharedVaultUsers/DeleteSharedVaultUserResponse'
import { SharedVaultUsersServerInterface } from './SharedVaultUsersServerInterface'
import { SharedVaultUsersPaths } from './Paths'
import { GetSharedVaultUsersResponse } from '../../Response/SharedVaultUsers/GetSharedVaultUsersResponse'
export class SharedVaultUsersServer implements SharedVaultUsersServerInterface {
constructor(private httpService: HttpServiceInterface) {}
getSharedVaultUsers(params: GetSharedVaultUsersRequestParams): Promise<HttpResponse<GetSharedVaultUsersResponse>> {
return this.httpService.get(SharedVaultUsersPaths.getSharedVaultUsers(params.sharedVaultUuid))
}
deleteSharedVaultUser(
params: DeleteSharedVaultUserRequestParams,
): Promise<HttpResponse<DeleteSharedVaultUserResponse>> {
return this.httpService.delete(SharedVaultUsersPaths.deleteSharedVaultUser(params.sharedVaultUuid, params.userUuid))
}
}
@@ -0,0 +1,13 @@
import { HttpResponse } from '@standardnotes/responses'
import { GetSharedVaultUsersRequestParams } from '../../Request/SharedVaultUser/GetSharedVaultUsersRequestParams'
import { DeleteSharedVaultUserRequestParams } from '../../Request/SharedVaultUser/DeleteSharedVaultUserRequestParams'
import { DeleteSharedVaultUserResponse } from '../../Response/SharedVaultUsers/DeleteSharedVaultUserResponse'
import { GetSharedVaultUsersResponse } from '../../Response/SharedVaultUsers/GetSharedVaultUsersResponse'
export interface SharedVaultUsersServerInterface {
getSharedVaultUsers(params: GetSharedVaultUsersRequestParams): Promise<HttpResponse<GetSharedVaultUsersResponse>>
deleteSharedVaultUser(
params: DeleteSharedVaultUserRequestParams,
): Promise<HttpResponse<DeleteSharedVaultUserResponse>>
}
@@ -1,5 +1,6 @@
const UserPaths = {
register: '/v1/users',
updateAccount: (userUuid: string) => `/v1/users/${userUuid}`,
deleteAccount: (userUuid: string) => `/v1/users/${userUuid}`,
}
@@ -1,3 +1,4 @@
import { UserUpdateResponse } from './../../Response/User/UserUpdateResponse'
import { HttpServiceInterface } from '../../Http/HttpServiceInterface'
import { UserDeletionRequestParams } from '../../Request/User/UserDeletionRequestParams'
import { UserRegistrationRequestParams } from '../../Request/User/UserRegistrationRequestParams'
@@ -6,6 +7,7 @@ import { UserDeletionResponseBody } from '../../Response/User/UserDeletionRespon
import { UserRegistrationResponseBody } from '../../Response/User/UserRegistrationResponseBody'
import { Paths } from './Paths'
import { UserServerInterface } from './UserServerInterface'
import { UserUpdateRequestParams } from '../../Request/User/UserUpdateRequestParams'
export class UserServer implements UserServerInterface {
constructor(private httpService: HttpServiceInterface) {}
@@ -17,4 +19,8 @@ export class UserServer implements UserServerInterface {
async register(params: UserRegistrationRequestParams): Promise<HttpResponse<UserRegistrationResponseBody>> {
return this.httpService.post(Paths.v1.register, params)
}
async update(params: UserUpdateRequestParams): Promise<HttpResponse<UserUpdateResponse>> {
return this.httpService.patch(Paths.v1.updateAccount(params.user_uuid), params)
}
}
@@ -3,8 +3,11 @@ import { UserDeletionRequestParams } from '../../Request/User/UserDeletionReques
import { UserRegistrationRequestParams } from '../../Request/User/UserRegistrationRequestParams'
import { UserDeletionResponseBody } from '../../Response/User/UserDeletionResponseBody'
import { UserRegistrationResponseBody } from '../../Response/User/UserRegistrationResponseBody'
import { UserUpdateResponse } from '../../Response/User/UserUpdateResponse'
import { UserUpdateRequestParams } from '../../Request/User/UserUpdateRequestParams'
export interface UserServerInterface {
register(params: UserRegistrationRequestParams): Promise<HttpResponse<UserRegistrationResponseBody>>
deleteAccount(params: UserDeletionRequestParams): Promise<HttpResponse<UserDeletionResponseBody>>
update(params: UserUpdateRequestParams): Promise<HttpResponse<UserUpdateResponse>>
}
+18
View File
@@ -1,14 +1,32 @@
export * from './Auth/AuthServer'
export * from './Auth/AuthServerInterface'
export * from './Authenticator/AuthenticatorServer'
export * from './Authenticator/AuthenticatorServerInterface'
export * from './Revision/RevisionServer'
export * from './Revision/RevisionServerInterface'
export * from './AsymmetricMessage/AsymmetricMessageServer'
export * from './AsymmetricMessage/AsymmetricMessageServerInterface'
export * from './SharedVault/SharedVaultServer'
export * from './SharedVault/SharedVaultServerInterface'
export * from './SharedVaultUsers/SharedVaultUsersServer'
export * from './SharedVaultUsers/SharedVaultUsersServerInterface'
export * from './Subscription/SubscriptionServer'
export * from './Subscription/SubscriptionServerInterface'
export * from './SharedVaultInvites/SharedVaultInvitesServer'
export * from './SharedVaultInvites/SharedVaultInvitesServerInterface'
export * from './User/UserServer'
export * from './User/UserServerInterface'
export * from './UserRequest/UserRequestServer'
export * from './UserRequest/UserRequestServerInterface'
export * from './WebSocket/WebSocketServer'
export * from './WebSocket/WebSocketServerInterface'
+32
View File
@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.58](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-30)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.57](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-29)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.56](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-27)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.55](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-27)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.54](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-26)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.53](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-26)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.52](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-26)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.51](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-25)
**Note:** Version bump only for package @standardnotes/clipper
## [1.1.50](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-25)
**Note:** Version bump only for package @standardnotes/clipper
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@standardnotes/clipper",
"description": "Web clipper browser extension for Standard Notes",
"version": "1.1.50",
"version": "1.1.58",
"private": true,
"scripts": {
"build-mv2": "yarn clean && webpack --config ./webpack.config.prod.js",
+32
View File
@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.106.67](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-30)
**Note:** Version bump only for package @standardnotes/desktop
## [3.106.66](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-29)
**Note:** Version bump only for package @standardnotes/desktop
## [3.106.65](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-27)
**Note:** Version bump only for package @standardnotes/desktop
## [3.106.64](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-27)
**Note:** Version bump only for package @standardnotes/desktop
## [3.106.63](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-26)
**Note:** Version bump only for package @standardnotes/desktop
## [3.106.62](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-26)
**Note:** Version bump only for package @standardnotes/desktop
## [3.106.61](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-26)
**Note:** Version bump only for package @standardnotes/desktop
## [3.106.60](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-25)
**Note:** Version bump only for package @standardnotes/desktop
## [3.106.59](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-25)
**Note:** Version bump only for package @standardnotes/desktop
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@standardnotes/desktop",
"main": "./app/dist/index.js",
"version": "3.106.59",
"version": "3.106.67",
"license": "AGPL-3.0-or-later",
"author": "Standard Notes.",
"private": true,
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.21.44](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-30)
**Note:** Version bump only for package @standardnotes/encryption
## [1.21.43](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-29)
**Note:** Version bump only for package @standardnotes/encryption
## [1.21.42](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-27)
**Note:** Version bump only for package @standardnotes/encryption
## [1.21.41](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-06-25)
**Note:** Version bump only for package @standardnotes/encryption
+6 -13
View File
@@ -1,26 +1,19 @@
{
"name": "@standardnotes/encryption",
"version": "1.21.41",
"version": "1.21.44",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
"description": "Payload encryption used in SNJS library",
"main": "dist/index.js",
"main": "./src/index.ts",
"private": true,
"author": "Standard Notes",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"license": "AGPL-3.0-or-later",
"scripts": {
"clean": "rm -fr dist",
"prestart": "yarn clean",
"start": "tsc -p tsconfig.json --watch",
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint src --ext .ts",
"format": "prettier --write src",
"test": "jest"
"test": "jest",
"build": "echo 'Empty build script required for yarn topological install'"
},
"devDependencies": {
"@standardnotes/config": "2.4.3",
@@ -35,7 +28,7 @@
"typescript": "*"
},
"dependencies": {
"@standardnotes/common": "^1.46.6",
"@standardnotes/common": "^1.48.3",
"@standardnotes/models": "workspace:*",
"@standardnotes/responses": "workspace:*",
"@standardnotes/sncrypto-common": "workspace:*",
+15 -3
View File
@@ -1,3 +1,5 @@
import { SodiumConstant } from '@standardnotes/sncrypto-common'
export const V001Algorithm = Object.freeze({
SaltSeedLength: 128,
/**
@@ -41,11 +43,21 @@ export enum V004Algorithm {
ArgonIterations = 5,
ArgonMemLimit = 67108864,
ArgonOutputKeyBytes = 64,
EncryptionKeyLength = 256,
EncryptionNonceLength = 192,
}
export enum V005Algorithm {
AsymmetricEncryptionNonceLength = 192,
SymmetricEncryptionNonceLength = 192,
MasterKeyEncryptionKeyPairSubKeyNumber = 1,
MasterKeyEncryptionKeyPairSubKeyContext = 'sn-pkc-e',
MasterKeyEncryptionKeyPairSubKeyBytes = SodiumConstant.crypto_box_SEEDBYTES,
MasterKeySigningKeyPairSubKeyNumber = 2,
MasterKeySigningKeyPairSubKeyContext = 'sn-pkc-s',
MasterKeySigningKeyPairSubKeyBytes = SodiumConstant.crypto_sign_SEEDBYTES,
PayloadKeyHashingKeySubKeyNumber = 1,
PayloadKeyHashingKeySubKeyContext = 'sn-sym-h',
PayloadKeyHashingKeySubKeyBytes = SodiumConstant.crypto_generichash_KEYBYTES,
}
@@ -7,11 +7,10 @@ import {
HistoryEntryInterface,
ItemsKeyContent,
ItemsKeyInterface,
RootKeyInterface,
} from '@standardnotes/models'
export function isItemsKey(x: ItemsKeyInterface | RootKeyInterface): x is ItemsKeyInterface {
return x.content_type === ContentType.ItemsKey
export function isItemsKey(x: unknown): x is ItemsKeyInterface {
return (x as ItemsKeyInterface).content_type === ContentType.ItemsKey
}
/**
@@ -0,0 +1,41 @@
import { ContentType, ProtocolVersion } from '@standardnotes/common'
import {
ConflictStrategy,
DecryptedItem,
DecryptedItemInterface,
DecryptedPayloadInterface,
HistoryEntryInterface,
KeySystemItemsKeyContent,
KeySystemItemsKeyInterface,
} from '@standardnotes/models'
export function isKeySystemItemsKey(x: unknown): x is KeySystemItemsKeyInterface {
return (x as KeySystemItemsKeyInterface).content_type === ContentType.KeySystemItemsKey
}
/**
* A key used to encrypt other items. Items keys are synced and persisted.
*/
export class KeySystemItemsKey extends DecryptedItem<KeySystemItemsKeyContent> implements KeySystemItemsKeyInterface {
creationTimestamp: number
keyVersion: ProtocolVersion
itemsKey: string
rootKeyToken: string
constructor(payload: DecryptedPayloadInterface<KeySystemItemsKeyContent>) {
super(payload)
this.creationTimestamp = payload.content.creationTimestamp
this.keyVersion = payload.content.version
this.itemsKey = this.payload.content.itemsKey
this.rootKeyToken = this.payload.content.rootKeyToken
}
/** Do not duplicate vault items keys. Always keep original */
override strategyWhenConflictingWithItem(
_item: DecryptedItemInterface,
_previousRevision?: HistoryEntryInterface,
): ConflictStrategy {
return ConflictStrategy.KeepBase
}
}
@@ -0,0 +1,3 @@
import { DecryptedItemMutator, KeySystemItemsKeyContent } from '@standardnotes/models'
export class KeySystemItemsKeyMutator extends DecryptedItemMutator<KeySystemItemsKeyContent> {}
@@ -0,0 +1,10 @@
import { ContentType } from '@standardnotes/common'
import { DecryptedItemMutator, KeySystemItemsKeyContent, RegisterItemClass } from '@standardnotes/models'
import { KeySystemItemsKey } from './KeySystemItemsKey'
import { KeySystemItemsKeyMutator } from './KeySystemItemsKeyMutator'
RegisterItemClass(
ContentType.KeySystemItemsKey,
KeySystemItemsKey,
KeySystemItemsKeyMutator as unknown as DecryptedItemMutator<KeySystemItemsKeyContent>,
)
@@ -5,11 +5,12 @@ import {
PayloadTimestampDefaults,
RootKeyContent,
RootKeyContentSpecialized,
RootKeyInterface,
} from '@standardnotes/models'
import { UuidGenerator } from '@standardnotes/utils'
import { SNRootKey } from './RootKey'
export function CreateNewRootKey(content: RootKeyContentSpecialized): SNRootKey {
export function CreateNewRootKey<K extends RootKeyInterface>(content: RootKeyContentSpecialized): K {
const uuid = UuidGenerator.GenerateUuid()
const payload = new DecryptedPayload<RootKeyContent>({
@@ -19,7 +20,7 @@ export function CreateNewRootKey(content: RootKeyContentSpecialized): SNRootKey
...PayloadTimestampDefaults(),
})
return new SNRootKey(payload)
return new SNRootKey(payload) as K
}
export function FillRootKeyContent(content: Partial<RootKeyContentSpecialized>): RootKeyContent {
@@ -37,15 +38,3 @@ export function FillRootKeyContent(content: Partial<RootKeyContentSpecialized>):
return FillItemContentSpecialized(content)
}
export function ContentTypeUsesRootKeyEncryption(contentType: ContentType): boolean {
return (
contentType === ContentType.RootKey ||
contentType === ContentType.ItemsKey ||
contentType === ContentType.EncryptedStorage
)
}
export function ItemContentTypeUsesRootKeyEncryption(contentType: ContentType): boolean {
return contentType === ContentType.ItemsKey
}
@@ -7,7 +7,7 @@ import {
RootKeyContentInStorage,
RootKeyInterface,
} from '@standardnotes/models'
import { timingSafeEqual } from '@standardnotes/sncrypto-common'
import { PkcKeyPair, timingSafeEqual } from '@standardnotes/sncrypto-common'
import { SNRootKeyParams } from './RootKeyParams'
/**
@@ -47,6 +47,14 @@ export class SNRootKey extends DecryptedItem<RootKeyContent> implements RootKeyI
return this.content.serverPassword
}
get encryptionKeyPair(): PkcKeyPair | undefined {
return this.content.encryptionKeyPair
}
get signingKeyPair(): PkcKeyPair | undefined {
return this.content.signingKeyPair
}
/** 003 and below only. */
public get dataAuthenticationKey(): string | undefined {
return this.content.dataAuthenticationKey
@@ -84,6 +92,8 @@ export class SNRootKey extends DecryptedItem<RootKeyContent> implements RootKeyI
const values: NamespacedRootKeyInKeychain = {
version: this.keyVersion,
masterKey: this.masterKey,
encryptionKeyPair: this.encryptionKeyPair,
signingKeyPair: this.signingKeyPair,
}
if (this.dataAuthenticationKey) {
@@ -8,8 +8,13 @@ import {
ItemsKeyContent,
ItemsKeyInterface,
PayloadTimestampDefaults,
KeySystemItemsKeyInterface,
KeySystemIdentifier,
KeySystemRootKeyInterface,
RootKeyInterface,
KeySystemRootKeyParamsInterface,
} from '@standardnotes/models'
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
import { PkcKeyPair, PureCryptoInterface } from '@standardnotes/sncrypto-common'
import { firstHalfOfString, secondHalfOfString, splitString, UuidGenerator } from '@standardnotes/utils'
import { V001Algorithm } from '../../Algorithm'
import { isItemsKey } from '../../Keys/ItemsKey/ItemsKey'
@@ -17,11 +22,16 @@ import { CreateNewRootKey } from '../../Keys/RootKey/Functions'
import { Create001KeyParams } from '../../Keys/RootKey/KeyParamsFunctions'
import { SNRootKey } from '../../Keys/RootKey/RootKey'
import { SNRootKeyParams } from '../../Keys/RootKey/RootKeyParams'
import { DecryptedParameters, EncryptedParameters, ErrorDecryptingParameters } from '../../Types/EncryptedParameters'
import { EncryptedOutputParameters, ErrorDecryptingParameters } from '../../Types/EncryptedParameters'
import { DecryptedParameters } from '../../Types/DecryptedParameters'
import { ItemAuthenticatedData } from '../../Types/ItemAuthenticatedData'
import { LegacyAttachedData } from '../../Types/LegacyAttachedData'
import { RootKeyEncryptedAuthenticatedData } from '../../Types/RootKeyEncryptedAuthenticatedData'
import { AsynchronousOperator } from '../Operator'
import { OperatorInterface } from '../OperatorInterface/OperatorInterface'
import { PublicKeySet } from '../Types/PublicKeySet'
import { AsymmetricDecryptResult } from '../Types/AsymmetricDecryptResult'
import { AsymmetricSignatureVerificationDetachedResult } from '../Types/AsymmetricSignatureVerificationDetachedResult'
import { AsyncOperatorInterface } from '../OperatorInterface/AsyncOperatorInterface'
const NO_IV = '00000000000000000000000000000000'
@@ -29,7 +39,7 @@ const NO_IV = '00000000000000000000000000000000'
* @deprecated
* A legacy operator no longer used to generate new accounts
*/
export class SNProtocolOperator001 implements AsynchronousOperator {
export class SNProtocolOperator001 implements OperatorInterface, AsyncOperatorInterface {
protected readonly crypto: PureCryptoInterface
constructor(crypto: PureCryptoInterface) {
@@ -68,11 +78,11 @@ export class SNProtocolOperator001 implements AsynchronousOperator {
return CreateDecryptedItemFromPayload(payload)
}
public async createRootKey(
public async createRootKey<K extends RootKeyInterface>(
identifier: string,
password: string,
origination: KeyParamsOrigination,
): Promise<SNRootKey> {
): Promise<K> {
const pwCost = V001Algorithm.PbkdfMinCost as number
const pwNonce = this.crypto.generateRandomKey(V001Algorithm.SaltSeedLength)
const pwSalt = await this.crypto.unsafeSha1(identifier + 'SN' + pwNonce)
@@ -90,13 +100,13 @@ export class SNProtocolOperator001 implements AsynchronousOperator {
return this.deriveKey(password, keyParams)
}
public getPayloadAuthenticatedData(
_encrypted: EncryptedParameters,
public getPayloadAuthenticatedDataForExternalUse(
_encrypted: EncryptedOutputParameters,
): RootKeyEncryptedAuthenticatedData | ItemAuthenticatedData | LegacyAttachedData | undefined {
return undefined
}
public async computeRootKey(password: string, keyParams: SNRootKeyParams): Promise<SNRootKey> {
public async computeRootKey<K extends RootKeyInterface>(password: string, keyParams: SNRootKeyParams): Promise<K> {
return this.deriveKey(password, keyParams)
}
@@ -111,7 +121,7 @@ export class SNProtocolOperator001 implements AsynchronousOperator {
public async generateEncryptedParametersAsync(
payload: DecryptedPayloadInterface,
key: ItemsKeyInterface | SNRootKey,
): Promise<EncryptedParameters> {
): Promise<EncryptedOutputParameters> {
/**
* Generate new item key that is double the key size.
* Will be split to create encryption key and authentication key.
@@ -132,16 +142,19 @@ export class SNProtocolOperator001 implements AsynchronousOperator {
return {
uuid: payload.uuid,
content_type: payload.content_type,
items_key_id: isItemsKey(key) ? key.uuid : undefined,
content: ciphertext,
enc_item_key: encItemKey,
auth_hash: authHash,
version: this.version,
key_system_identifier: payload.key_system_identifier,
shared_vault_uuid: payload.shared_vault_uuid,
}
}
public async generateDecryptedParametersAsync<C extends ItemContent = ItemContent>(
encrypted: EncryptedParameters,
encrypted: EncryptedOutputParameters,
key: ItemsKeyInterface | SNRootKey,
): Promise<DecryptedParameters<C> | ErrorDecryptingParameters> {
if (!encrypted.enc_item_key) {
@@ -178,6 +191,7 @@ export class SNProtocolOperator001 implements AsynchronousOperator {
return {
uuid: encrypted.uuid,
content: JSON.parse(content),
signatureData: { required: false, contentHash: '' },
}
}
}
@@ -191,7 +205,7 @@ export class SNProtocolOperator001 implements AsynchronousOperator {
}
}
protected async deriveKey(password: string, keyParams: SNRootKeyParams): Promise<SNRootKey> {
protected async deriveKey<K extends RootKeyInterface>(password: string, keyParams: SNRootKeyParams): Promise<K> {
const derivedKey = await this.crypto.pbkdf2(
password,
keyParams.content001.pw_salt,
@@ -205,11 +219,63 @@ export class SNProtocolOperator001 implements AsynchronousOperator {
const partitions = splitString(derivedKey, 2)
return CreateNewRootKey({
return CreateNewRootKey<K>({
serverPassword: partitions[0],
masterKey: partitions[1],
version: ProtocolVersion.V001,
keyParams: keyParams.getPortableValue(),
})
}
createRandomizedKeySystemRootKey(_dto: { systemIdentifier: string }): KeySystemRootKeyInterface {
throw new Error('Method not implemented.')
}
createUserInputtedKeySystemRootKey(_dto: {
systemIdentifier: string
systemName: string
userInputtedPassword: string
}): KeySystemRootKeyInterface {
throw new Error('Method not implemented.')
}
deriveUserInputtedKeySystemRootKey(_dto: {
keyParams: KeySystemRootKeyParamsInterface
userInputtedPassword: string
}): KeySystemRootKeyInterface {
throw new Error('Method not implemented.')
}
createKeySystemItemsKey(
_uuid: string,
_keySystemIdentifier: KeySystemIdentifier,
_sharedVaultUuid: string | undefined,
): KeySystemItemsKeyInterface {
throw new Error('Method not implemented.')
}
versionForAsymmetricallyEncryptedString(_encryptedString: string): ProtocolVersion {
throw new Error('Method not implemented.')
}
asymmetricEncrypt(_dto: {
stringToEncrypt: string
senderKeyPair: PkcKeyPair
senderSigningKeyPair: PkcKeyPair
recipientPublicKey: string
}): string {
throw new Error('Method not implemented.')
}
asymmetricDecrypt(_dto: { stringToDecrypt: string; recipientSecretKey: string }): AsymmetricDecryptResult | null {
throw new Error('Method not implemented.')
}
asymmetricSignatureVerifyDetached(_encryptedString: string): AsymmetricSignatureVerificationDetachedResult {
throw new Error('Method not implemented.')
}
getSenderPublicKeySetFromAsymmetricallyEncryptedString(_string: string): PublicKeySet {
throw new Error('Method not implemented.')
}
}
@@ -9,7 +9,8 @@ import { CreateNewRootKey } from '../../Keys/RootKey/Functions'
import { Create002KeyParams } from '../../Keys/RootKey/KeyParamsFunctions'
import { SNRootKey } from '../../Keys/RootKey/RootKey'
import { SNRootKeyParams } from '../../Keys/RootKey/RootKeyParams'
import { DecryptedParameters, EncryptedParameters, ErrorDecryptingParameters } from '../../Types/EncryptedParameters'
import { EncryptedOutputParameters, ErrorDecryptingParameters } from '../../Types/EncryptedParameters'
import { DecryptedParameters } from '../../Types/DecryptedParameters'
import { ItemAuthenticatedData } from '../../Types/ItemAuthenticatedData'
import { LegacyAttachedData } from '../../Types/LegacyAttachedData'
import { RootKeyEncryptedAuthenticatedData } from '../../Types/RootKeyEncryptedAuthenticatedData'
@@ -50,11 +51,11 @@ export class SNProtocolOperator002 extends SNProtocolOperator001 {
return Models.CreateDecryptedItemFromPayload(payload)
}
public override async createRootKey(
public override async createRootKey<K extends Models.RootKeyInterface>(
identifier: string,
password: string,
origination: Common.KeyParamsOrigination,
): Promise<SNRootKey> {
): Promise<K> {
const pwCost = Utils.lastElement(V002Algorithm.PbkdfCostsUsed) as number
const pwNonce = this.crypto.generateRandomKey(V002Algorithm.SaltSeedLength)
const pwSalt = await this.crypto.unsafeSha1(identifier + ':' + pwNonce)
@@ -77,7 +78,10 @@ export class SNProtocolOperator002 extends SNProtocolOperator001 {
* may have had costs of 5000, and others of 101000. Therefore, when computing
* the root key, we must use the value returned by the server.
*/
public override async computeRootKey(password: string, keyParams: SNRootKeyParams): Promise<SNRootKey> {
public override async computeRootKey<K extends Models.RootKeyInterface>(
password: string,
keyParams: SNRootKeyParams,
): Promise<K> {
return this.deriveKey(password, keyParams)
}
@@ -141,8 +145,8 @@ export class SNProtocolOperator002 extends SNProtocolOperator001 {
return this.decryptString002(contentCiphertext, encryptionKey, iv)
}
public override getPayloadAuthenticatedData(
encrypted: EncryptedParameters,
public override getPayloadAuthenticatedDataForExternalUse(
encrypted: EncryptedOutputParameters,
): RootKeyEncryptedAuthenticatedData | ItemAuthenticatedData | LegacyAttachedData | undefined {
const itemKeyComponents = this.encryptionComponentsFromString002(encrypted.enc_item_key)
const authenticatedData = itemKeyComponents.keyParams
@@ -161,7 +165,7 @@ export class SNProtocolOperator002 extends SNProtocolOperator001 {
public override async generateEncryptedParametersAsync(
payload: Models.DecryptedPayloadInterface,
key: Models.ItemsKeyInterface | SNRootKey,
): Promise<EncryptedParameters> {
): Promise<EncryptedOutputParameters> {
/**
* Generate new item key that is double the key size.
* Will be split to create encryption key and authentication key.
@@ -189,15 +193,18 @@ export class SNProtocolOperator002 extends SNProtocolOperator001 {
return {
uuid: payload.uuid,
content_type: payload.content_type,
items_key_id: isItemsKey(key) ? key.uuid : undefined,
content: ciphertext,
enc_item_key: encItemKey,
version: this.version,
key_system_identifier: payload.key_system_identifier,
shared_vault_uuid: payload.shared_vault_uuid,
}
}
public override async generateDecryptedParametersAsync<C extends ItemContent = ItemContent>(
encrypted: EncryptedParameters,
encrypted: EncryptedOutputParameters,
key: Models.ItemsKeyInterface | SNRootKey,
): Promise<DecryptedParameters<C> | ErrorDecryptingParameters> {
if (!encrypted.enc_item_key) {
@@ -252,11 +259,15 @@ export class SNProtocolOperator002 extends SNProtocolOperator001 {
return {
uuid: encrypted.uuid,
content: JSON.parse(content),
signatureData: { required: false, contentHash: '' },
}
}
}
protected override async deriveKey(password: string, keyParams: SNRootKeyParams): Promise<SNRootKey> {
protected override async deriveKey<K extends Models.RootKeyInterface>(
password: string,
keyParams: SNRootKeyParams,
): Promise<K> {
const derivedKey = await this.crypto.pbkdf2(
password,
keyParams.content002.pw_salt,
@@ -270,7 +281,7 @@ export class SNProtocolOperator002 extends SNProtocolOperator001 {
const partitions = Utils.splitString(derivedKey, 3)
return CreateNewRootKey({
return CreateNewRootKey<K>({
serverPassword: partitions[0],
masterKey: partitions[1],
dataAuthenticationKey: partitions[2],
@@ -6,12 +6,12 @@ import {
ItemsKeyContent,
ItemsKeyInterface,
PayloadTimestampDefaults,
RootKeyInterface,
} from '@standardnotes/models'
import { splitString, UuidGenerator } from '@standardnotes/utils'
import { V003Algorithm } from '../../Algorithm'
import { CreateNewRootKey } from '../../Keys/RootKey/Functions'
import { Create003KeyParams } from '../../Keys/RootKey/KeyParamsFunctions'
import { SNRootKey } from '../../Keys/RootKey/RootKey'
import { SNRootKeyParams } from '../../Keys/RootKey/RootKeyParams'
import { SNProtocolOperator002 } from '../002/Operator002'
@@ -53,11 +53,17 @@ export class SNProtocolOperator003 extends SNProtocolOperator002 {
return CreateDecryptedItemFromPayload(payload)
}
public override async computeRootKey(password: string, keyParams: SNRootKeyParams): Promise<SNRootKey> {
public override async computeRootKey<K extends RootKeyInterface>(
password: string,
keyParams: SNRootKeyParams,
): Promise<K> {
return this.deriveKey(password, keyParams)
}
protected override async deriveKey(password: string, keyParams: SNRootKeyParams): Promise<SNRootKey> {
protected override async deriveKey<K extends RootKeyInterface>(
password: string,
keyParams: SNRootKeyParams,
): Promise<K> {
const salt = await this.generateSalt(
keyParams.content003.identifier,
ProtocolVersion.V003,
@@ -78,7 +84,7 @@ export class SNProtocolOperator003 extends SNProtocolOperator002 {
const partitions = splitString(derivedKey, 3)
return CreateNewRootKey({
return CreateNewRootKey<K>({
serverPassword: partitions[0],
masterKey: partitions[1],
dataAuthenticationKey: partitions[2],
@@ -87,11 +93,11 @@ export class SNProtocolOperator003 extends SNProtocolOperator002 {
})
}
public override async createRootKey(
public override async createRootKey<K extends RootKeyInterface>(
identifier: string,
password: string,
origination: KeyParamsOrigination,
): Promise<SNRootKey> {
): Promise<K> {
const version = ProtocolVersion.V003
const pwNonce = this.crypto.generateRandomKey(V003Algorithm.SaltSeedLength)
const keyParams = Create003KeyParams({
@@ -0,0 +1,87 @@
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
export function getMockedCrypto(): PureCryptoInterface {
const crypto = {} as jest.Mocked<PureCryptoInterface>
const mockGenerateKeyPair = (seed: string) => {
const publicKey = `public-key-${seed}`
const privateKey = `private-key-${seed}`
return {
publicKey: `${publicKey}:${privateKey}`,
privateKey: `${privateKey}:${publicKey}`,
}
}
const replaceColonsToAvoidJSONConflicts = (text: string) => {
return text.replace(/:/g, '|')
}
const undoReplaceColonsToAvoidJSONConflicts = (text: string) => {
return text.replace(/\|/g, ':')
}
crypto.base64Encode = jest.fn().mockImplementation((text: string) => {
return `base64-${replaceColonsToAvoidJSONConflicts(text)}`
})
crypto.base64Decode = jest.fn().mockImplementation((text: string) => {
const decodedText = text.split('base64-')[1]
return undoReplaceColonsToAvoidJSONConflicts(decodedText)
})
crypto.xchacha20Encrypt = jest.fn().mockImplementation((text: string) => {
return `<e>${replaceColonsToAvoidJSONConflicts(text)}<e>`
})
crypto.xchacha20Decrypt = jest.fn().mockImplementation((text: string) => {
return undoReplaceColonsToAvoidJSONConflicts(text.split('<e>')[1])
})
crypto.generateRandomKey = jest.fn().mockImplementation(() => {
return 'random-string'
})
crypto.sodiumCryptoBoxEasyEncrypt = jest.fn().mockImplementation((text: string) => {
return `<e>${replaceColonsToAvoidJSONConflicts(text)}<e>`
})
crypto.sodiumCryptoBoxEasyDecrypt = jest.fn().mockImplementation((text: string) => {
return undoReplaceColonsToAvoidJSONConflicts(text.split('<e>')[1])
})
crypto.sodiumCryptoBoxSeedKeypair = jest.fn().mockImplementation((seed: string) => {
return mockGenerateKeyPair(seed)
})
crypto.sodiumCryptoKdfDeriveFromKey = jest
.fn()
.mockImplementation((key: string, subkeyNumber: number, subkeyLength: number, context: string) => {
return `subkey-${key}-${subkeyNumber}-${subkeyLength}-${context}`
})
crypto.sodiumCryptoSign = jest.fn().mockImplementation((message: string, privateKey: string) => {
const signature = `signature:m=${message}:pk=${privateKey}`
return signature
})
crypto.sodiumCryptoSignSeedKeypair = jest.fn().mockImplementation((seed: string) => {
return mockGenerateKeyPair(seed)
})
crypto.sodiumCryptoSignVerify = jest
.fn()
.mockImplementation((message: string, signature: string, publicKey: string) => {
const keyComponents = publicKey.split(':')
const privateKeyComponent = keyComponents[1]
const privateKey = `${privateKeyComponent}:${keyComponents[0]}`
const computedSignature = crypto.sodiumCryptoSign(message, privateKey)
return computedSignature === signature
})
crypto.sodiumCryptoGenericHash = jest.fn().mockImplementation((message: string, key: string) => {
return `hash-${message}-${key}`
})
return crypto
}

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