diff --git a/packages/api/src/Domain/Http/HttpRequestOptions.ts b/packages/api/src/Domain/Http/HttpRequestOptions.ts new file mode 100644 index 000000000..efeb9ebc9 --- /dev/null +++ b/packages/api/src/Domain/Http/HttpRequestOptions.ts @@ -0,0 +1,4 @@ +export interface HttpRequestOptions { + authentication?: string + headers?: Record[] +} diff --git a/packages/api/src/Domain/Http/HttpService.ts b/packages/api/src/Domain/Http/HttpService.ts index 3a9fba440..68b6bc79b 100644 --- a/packages/api/src/Domain/Http/HttpService.ts +++ b/packages/api/src/Domain/Http/HttpService.ts @@ -16,6 +16,7 @@ import { Paths } from '../Server/Auth/Paths' import { SessionRefreshResponseBody } from '../Response/Auth/SessionRefreshResponseBody' import { FetchRequestHandler } from './FetchRequestHandler' import { RequestHandlerInterface } from './RequestHandlerInterface' +import { HttpRequestOptions } from './HttpRequestOptions' export class HttpService implements HttpServiceInterface { private session?: Session | LegacySession @@ -76,7 +77,7 @@ export class HttpService implements HttpServiceInterface { } } - async get(path: string, params?: HttpRequestParams, authentication?: string): Promise> { + async get(path: string, params?: HttpRequestParams, options?: HttpRequestOptions): Promise> { if (!this.host) { throw new Error('Attempting to make network request before host is set') } @@ -85,7 +86,7 @@ export class HttpService implements HttpServiceInterface { url: joinPaths(this.host, path), params, verb: HttpVerb.Get, - authentication: authentication ?? this.getSessionAccessToken(), + authentication: options?.authentication ?? this.getSessionAccessToken(), }) } @@ -98,7 +99,7 @@ export class HttpService implements HttpServiceInterface { }) } - async post(path: string, params?: HttpRequestParams, authentication?: string): Promise> { + async post(path: string, params?: HttpRequestParams, options?: HttpRequestOptions): Promise> { if (!this.host) { throw new Error('Attempting to make network request before host is set') } @@ -107,34 +108,35 @@ export class HttpService implements HttpServiceInterface { url: joinPaths(this.host, path), params, verb: HttpVerb.Post, - authentication: authentication ?? this.getSessionAccessToken(), + authentication: options?.authentication ?? this.getSessionAccessToken(), + customHeaders: options?.headers, }) } - async put(path: string, params?: HttpRequestParams, authentication?: string): Promise> { + async put(path: string, params?: HttpRequestParams, options?: HttpRequestOptions): Promise> { return this.runHttp({ url: joinPaths(this.host, path), params, verb: HttpVerb.Put, - authentication: authentication ?? this.getSessionAccessToken(), + authentication: options?.authentication ?? this.getSessionAccessToken(), }) } - async patch(path: string, params: HttpRequestParams, authentication?: string): Promise> { + async patch(path: string, params: HttpRequestParams, options?: HttpRequestOptions): Promise> { return this.runHttp({ url: joinPaths(this.host, path), params, verb: HttpVerb.Patch, - authentication: authentication ?? this.getSessionAccessToken(), + authentication: options?.authentication ?? this.getSessionAccessToken(), }) } - async delete(path: string, params?: HttpRequestParams, authentication?: string): Promise> { + async delete(path: string, params?: HttpRequestParams, options?: HttpRequestOptions): Promise> { return this.runHttp({ url: joinPaths(this.host, path), params, verb: HttpVerb.Delete, - authentication: authentication ?? this.getSessionAccessToken(), + authentication: options?.authentication ?? this.getSessionAccessToken(), }) } diff --git a/packages/api/src/Domain/Http/HttpServiceInterface.ts b/packages/api/src/Domain/Http/HttpServiceInterface.ts index 3da00b93c..421fa347c 100644 --- a/packages/api/src/Domain/Http/HttpServiceInterface.ts +++ b/packages/api/src/Domain/Http/HttpServiceInterface.ts @@ -1,16 +1,18 @@ import { LegacySession, Session } from '@standardnotes/domain-core' import { HttpRequest, HttpRequestParams, HttpResponse, HttpResponseMeta } from '@standardnotes/responses' +import { HttpRequestOptions } from './HttpRequestOptions' + export interface HttpServiceInterface { setHost(host: string): void getHost(): string - get(path: string, params?: HttpRequestParams, authentication?: string): Promise> + get(path: string, params?: HttpRequestParams, options?: HttpRequestOptions): Promise> getExternal(url: string, params?: HttpRequestParams): Promise> - post(path: string, params?: HttpRequestParams, authentication?: string): Promise> - put(path: string, params?: HttpRequestParams, authentication?: string): Promise> - patch(path: string, params: HttpRequestParams, authentication?: string): Promise> - delete(path: string, params?: HttpRequestParams, authentication?: string): Promise> + post(path: string, params?: HttpRequestParams, options?: HttpRequestOptions): Promise> + put(path: string, params?: HttpRequestParams, options?: HttpRequestOptions): Promise> + patch(path: string, params: HttpRequestParams, options?: HttpRequestOptions): Promise> + delete(path: string, params?: HttpRequestParams, options?: HttpRequestOptions): Promise> runHttp(httpRequest: HttpRequest): Promise> setSession(session: Session | LegacySession): void diff --git a/packages/api/src/Domain/Http/index.ts b/packages/api/src/Domain/Http/index.ts index 043bf7426..119da638d 100644 --- a/packages/api/src/Domain/Http/index.ts +++ b/packages/api/src/Domain/Http/index.ts @@ -1,4 +1,5 @@ export * from './HttpService' export * from './FetchRequestHandler' +export * from './HttpRequestOptions' export * from './HttpServiceInterface' export * from './XMLHttpRequestState' diff --git a/packages/api/src/Domain/Request/SharedVault/CreateSharedVaultValetTokenParams.ts b/packages/api/src/Domain/Request/SharedVault/CreateSharedVaultValetTokenParams.ts index 308117a58..3dd727c1b 100644 --- a/packages/api/src/Domain/Request/SharedVault/CreateSharedVaultValetTokenParams.ts +++ b/packages/api/src/Domain/Request/SharedVault/CreateSharedVaultValetTokenParams.ts @@ -8,4 +8,5 @@ export type CreateSharedVaultValetTokenParams = { unencryptedFileSize?: number moveOperationType?: SharedVaultMoveType sharedVaultToSharedVaultMoveTargetUuid?: string + sharedVaultOwnerUuid?: string } diff --git a/packages/api/src/Domain/Server/SharedVault/SharedVaultServer.ts b/packages/api/src/Domain/Server/SharedVault/SharedVaultServer.ts index f8e719cb2..4ee7fd7fa 100644 --- a/packages/api/src/Domain/Server/SharedVault/SharedVaultServer.ts +++ b/packages/api/src/Domain/Server/SharedVault/SharedVaultServer.ts @@ -25,13 +25,23 @@ export class SharedVaultServer implements SharedVaultServerInterface { createSharedVaultFileValetToken( params: CreateSharedVaultValetTokenParams, ): Promise> { - 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, - }) + let headers = undefined + if (params.sharedVaultOwnerUuid) { + headers = [{ 'x-shared-vault-owner-context': params.sharedVaultOwnerUuid }] + } + 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, + }, + { + headers, + }, + ) } } diff --git a/packages/responses/src/Domain/SharedVaults/SharedVaultServerHash.ts b/packages/responses/src/Domain/SharedVaults/SharedVaultServerHash.ts index 0134b5ffb..a0c0b2efe 100644 --- a/packages/responses/src/Domain/SharedVaults/SharedVaultServerHash.ts +++ b/packages/responses/src/Domain/SharedVaults/SharedVaultServerHash.ts @@ -2,7 +2,6 @@ export interface SharedVaultServerHash { uuid: string user_uuid: string file_upload_bytes_used: number - file_upload_bytes_limit: number created_at_timestamp: number updated_at_timestamp: number } diff --git a/packages/services/src/Domain/Files/FileService.ts b/packages/services/src/Domain/Files/FileService.ts index 8a85cd490..cf94a0320 100644 --- a/packages/services/src/Domain/Files/FileService.ts +++ b/packages/services/src/Domain/Files/FileService.ts @@ -107,6 +107,7 @@ export class FileService extends AbstractService implements FilesClientInterface unencryptedFileSizeForUpload?: number | undefined moveOperationType?: SharedVaultMoveType sharedVaultToSharedVaultMoveTargetUuid?: string + sharedVaultOwnerUuid?: string }): Promise { if (params.operation !== ValetTokenOperation.Write && !params.fileUuidRequiredForExistingFiles) { throw new Error('File UUID is required for for non-write operations') @@ -114,6 +115,7 @@ export class FileService extends AbstractService implements FilesClientInterface const valetTokenResponse = await this.sharedVault.createSharedVaultFileValetToken({ sharedVaultUuid: params.sharedVaultUuid, + sharedVaultOwnerUuid: params.sharedVaultUuid, fileUuid: params.fileUuidRequiredForExistingFiles, remoteIdentifier: params.remoteIdentifier, operation: params.operation, @@ -135,6 +137,7 @@ export class FileService extends AbstractService implements FilesClientInterface ): Promise { const valetTokenResult = await this.createSharedVaultValetToken({ sharedVaultUuid: file.shared_vault_uuid ? file.shared_vault_uuid : sharedVault.sharing.sharedVaultUuid, + sharedVaultOwnerUuid: sharedVault.sharing.ownerUserUuid, remoteIdentifier: file.remoteIdentifier, operation: ValetTokenOperation.Move, fileUuidRequiredForExistingFiles: file.uuid, @@ -186,6 +189,7 @@ export class FileService extends AbstractService implements FilesClientInterface vault && vault.isSharedVaultListing() ? await this.createSharedVaultValetToken({ sharedVaultUuid: vault.sharing.sharedVaultUuid, + sharedVaultOwnerUuid: vault.sharing.ownerUserUuid, remoteIdentifier, operation: ValetTokenOperation.Write, unencryptedFileSizeForUpload: sizeInBytes, diff --git a/packages/services/src/Domain/SharedVaults/UseCase/SyncLocalVaultsWithRemoteSharedVaults.spec.ts b/packages/services/src/Domain/SharedVaults/UseCase/SyncLocalVaultsWithRemoteSharedVaults.spec.ts index dff7e572a..66ce81a08 100644 --- a/packages/services/src/Domain/SharedVaults/UseCase/SyncLocalVaultsWithRemoteSharedVaults.spec.ts +++ b/packages/services/src/Domain/SharedVaults/UseCase/SyncLocalVaultsWithRemoteSharedVaults.spec.ts @@ -13,7 +13,6 @@ describe('SyncLocalVaultsWithRemoteSharedVaults', () => { uuid: '1-2-3', user_uuid: '2-3-4', file_upload_bytes_used: 123, - file_upload_bytes_limit: 10000000, created_at_timestamp: 123, updated_at_timestamp: 123, }] } }) diff --git a/packages/snjs/lib/Services/Api/ApiService.ts b/packages/snjs/lib/Services/Api/ApiService.ts index f250cfca9..f409b663a 100644 --- a/packages/snjs/lib/Services/Api/ApiService.ts +++ b/packages/snjs/lib/Services/Api/ApiService.ts @@ -318,7 +318,9 @@ export class LegacyApiService } signOut(): Promise> { - return this.httpService.post(Paths.v1.signOut, undefined, this.getSessionAccessToken()) + return this.httpService.post(Paths.v1.signOut, undefined, { + authentication: this.getSessionAccessToken(), + }) } async changeCredentials(parameters: { @@ -344,7 +346,9 @@ export class LegacyApiService ...parameters.newKeyParams.getPortableValue(), }) - const response = await this.httpService.put(path, params, this.getSessionAccessToken()) + const response = await this.httpService.put(path, params, { + authentication: this.getSessionAccessToken(), + }) this.changing = false @@ -481,7 +485,11 @@ export class LegacyApiService return preprocessingError } const path = Paths.v1.sessions - const response = await this.httpService.get(path, {}, this.getSessionAccessToken()) + const response = await this.httpService.get( + path, + {}, + { authentication: this.getSessionAccessToken() }, + ) if (isErrorResponse(response)) { this.preprocessAuthenticatedErrorResponse(response) @@ -502,7 +510,7 @@ export class LegacyApiService const response = await this.httpService.delete( path, { uuid: sessionId }, - this.getSessionAccessToken(), + { authentication: this.getSessionAccessToken() }, ) if (isErrorResponse(response)) {