@fluidframework/odsp-driver 0.55.0 → 0.56.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/checkUrl.d.ts.map +1 -1
- package/dist/checkUrl.js +0 -1
- package/dist/checkUrl.js.map +1 -1
- package/dist/contractsPublic.d.ts +7 -1
- package/dist/contractsPublic.d.ts.map +1 -1
- package/dist/contractsPublic.js +7 -1
- package/dist/contractsPublic.js.map +1 -1
- package/dist/createFile.d.ts +3 -3
- package/dist/createFile.d.ts.map +1 -1
- package/dist/createFile.js +7 -7
- package/dist/createFile.js.map +1 -1
- package/dist/epochTracker.d.ts +3 -3
- package/dist/epochTracker.d.ts.map +1 -1
- package/dist/epochTracker.js +20 -8
- package/dist/epochTracker.js.map +1 -1
- package/dist/fetchSnapshot.d.ts +3 -2
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +28 -16
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/getFileLink.js +4 -4
- package/dist/getFileLink.js.map +1 -1
- package/dist/getUrlAndHeadersWithAuth.d.ts +1 -1
- package/dist/getUrlAndHeadersWithAuth.d.ts.map +1 -1
- package/dist/getUrlAndHeadersWithAuth.js +20 -33
- package/dist/getUrlAndHeadersWithAuth.js.map +1 -1
- package/dist/odspDeltaStorageService.d.ts.map +1 -1
- package/dist/odspDeltaStorageService.js +1 -4
- package/dist/odspDeltaStorageService.js.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.js +2 -2
- package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
- package/dist/odspDocumentStorageManager.d.ts +1 -0
- package/dist/odspDocumentStorageManager.d.ts.map +1 -1
- package/dist/odspDocumentStorageManager.js +16 -9
- package/dist/odspDocumentStorageManager.js.map +1 -1
- package/dist/odspDriverUrlResolver.d.ts.map +1 -1
- package/dist/odspDriverUrlResolver.js +5 -2
- package/dist/odspDriverUrlResolver.js.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.js +1 -2
- package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/dist/odspSummaryUploadManager.d.ts +2 -1
- package/dist/odspSummaryUploadManager.d.ts.map +1 -1
- package/dist/odspSummaryUploadManager.js +3 -2
- package/dist/odspSummaryUploadManager.js.map +1 -1
- package/dist/odspUtils.d.ts.map +1 -1
- package/dist/odspUtils.js +4 -1
- package/dist/odspUtils.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/prefetchLatestSnapshot.d.ts +2 -1
- package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
- package/dist/prefetchLatestSnapshot.js +3 -2
- package/dist/prefetchLatestSnapshot.js.map +1 -1
- package/dist/retryErrorsStorageAdapter.d.ts +1 -1
- package/dist/retryErrorsStorageAdapter.d.ts.map +1 -1
- package/dist/retryErrorsStorageAdapter.js.map +1 -1
- package/lib/checkUrl.d.ts.map +1 -1
- package/lib/checkUrl.js +0 -1
- package/lib/checkUrl.js.map +1 -1
- package/lib/contractsPublic.d.ts +7 -1
- package/lib/contractsPublic.d.ts.map +1 -1
- package/lib/contractsPublic.js +6 -0
- package/lib/contractsPublic.js.map +1 -1
- package/lib/createFile.d.ts +3 -3
- package/lib/createFile.d.ts.map +1 -1
- package/lib/createFile.js +7 -7
- package/lib/createFile.js.map +1 -1
- package/lib/epochTracker.d.ts +3 -3
- package/lib/epochTracker.d.ts.map +1 -1
- package/lib/epochTracker.js +21 -9
- package/lib/epochTracker.js.map +1 -1
- package/lib/fetchSnapshot.d.ts +3 -2
- package/lib/fetchSnapshot.d.ts.map +1 -1
- package/lib/fetchSnapshot.js +28 -16
- package/lib/fetchSnapshot.js.map +1 -1
- package/lib/getFileLink.js +4 -4
- package/lib/getFileLink.js.map +1 -1
- package/lib/getUrlAndHeadersWithAuth.d.ts +1 -1
- package/lib/getUrlAndHeadersWithAuth.d.ts.map +1 -1
- package/lib/getUrlAndHeadersWithAuth.js +20 -33
- package/lib/getUrlAndHeadersWithAuth.js.map +1 -1
- package/lib/odspDeltaStorageService.d.ts.map +1 -1
- package/lib/odspDeltaStorageService.js +1 -4
- package/lib/odspDeltaStorageService.js.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.js +2 -2
- package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
- package/lib/odspDocumentStorageManager.d.ts +1 -0
- package/lib/odspDocumentStorageManager.d.ts.map +1 -1
- package/lib/odspDocumentStorageManager.js +16 -9
- package/lib/odspDocumentStorageManager.js.map +1 -1
- package/lib/odspDriverUrlResolver.d.ts.map +1 -1
- package/lib/odspDriverUrlResolver.js +5 -2
- package/lib/odspDriverUrlResolver.js.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.js +1 -2
- package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/lib/odspSummaryUploadManager.d.ts +2 -1
- package/lib/odspSummaryUploadManager.d.ts.map +1 -1
- package/lib/odspSummaryUploadManager.js +3 -2
- package/lib/odspSummaryUploadManager.js.map +1 -1
- package/lib/odspUtils.d.ts.map +1 -1
- package/lib/odspUtils.js +5 -2
- package/lib/odspUtils.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/prefetchLatestSnapshot.d.ts +2 -1
- package/lib/prefetchLatestSnapshot.d.ts.map +1 -1
- package/lib/prefetchLatestSnapshot.js +3 -2
- package/lib/prefetchLatestSnapshot.js.map +1 -1
- package/lib/retryErrorsStorageAdapter.d.ts +1 -1
- package/lib/retryErrorsStorageAdapter.d.ts.map +1 -1
- package/lib/retryErrorsStorageAdapter.js.map +1 -1
- package/package.json +9 -9
- package/src/checkUrl.ts +0 -1
- package/src/contractsPublic.ts +11 -1
- package/src/createFile.ts +16 -4
- package/src/epochTracker.ts +21 -6
- package/src/fetchSnapshot.ts +33 -16
- package/src/getFileLink.ts +7 -2
- package/src/getUrlAndHeadersWithAuth.ts +24 -38
- package/src/odspDeltaStorageService.ts +1 -3
- package/src/odspDocumentServiceFactoryCore.ts +1 -0
- package/src/odspDocumentStorageManager.ts +39 -8
- package/src/odspDriverUrlResolver.ts +3 -0
- package/src/odspDriverUrlResolverForShareLink.ts +1 -2
- package/src/odspSummaryUploadManager.ts +6 -1
- package/src/odspUtils.ts +13 -3
- package/src/packageVersion.ts +1 -1
- package/src/prefetchLatestSnapshot.ts +3 -0
- package/src/retryErrorsStorageAdapter.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retryErrorsStorageAdapter.d.ts","sourceRoot":"","sources":["../src/retryErrorsStorageAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACH,uBAAuB,EACvB,+BAA+B,EAC/B,eAAe,EAClB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,KAAK,EACL,QAAQ,EACX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGnF,qBAAa,yBAA0B,YAAW,uBAAuB,EAAE,WAAW;IAG9E,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAH3B,OAAO,CAAC,SAAS,CAAS;gBAEL,sBAAsB,EAAE,uBAAuB,EAC/C,MAAM,EAAE,gBAAgB;IAI7C,IAAW,QAAQ,IAAI,+BAA+B,GAAG,SAAS,CAEjE;IACD,IAAW,QAAQ,YAA2B;IACvC,OAAO;IAId,IAAW,aAAa,IAAI,MAAM,CAEjC;IAEY,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAOlE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAO9C,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"retryErrorsStorageAdapter.d.ts","sourceRoot":"","sources":["../src/retryErrorsStorageAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACH,uBAAuB,EACvB,+BAA+B,EAC/B,eAAe,EAClB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,KAAK,EACL,QAAQ,EACX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGnF,qBAAa,yBAA0B,YAAW,uBAAuB,EAAE,WAAW;IAG9E,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAH3B,OAAO,CAAC,SAAS,CAAS;gBAEL,sBAAsB,EAAE,uBAAuB,EAC/C,MAAM,EAAE,gBAAgB;IAI7C,IAAW,QAAQ,IAAI,+BAA+B,GAAG,SAAS,CAEjE;IACD,IAAW,QAAQ,YAA2B;IACvC,OAAO;IAId,IAAW,aAAa,IAAI,MAAM,CAEjC;IAEY,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAOlE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAO9C,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAOzE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOtF,wBAAwB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ1F,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAO9D,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAO5E,OAAO,CAAC,oBAAoB;YAMd,YAAY;CAQ7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retryErrorsStorageAdapter.js","sourceRoot":"","sources":["../src/retryErrorsStorageAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAe/D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,OAAO,yBAAyB;IAElC,YACqB,sBAA+C,EAC/C,MAAwB;QADxB,2BAAsB,GAAtB,sBAAsB,CAAyB;QAC/C,WAAM,GAAN,MAAM,CAAkB;QAHrC,cAAS,GAAG,KAAK,CAAC;IAK1B,CAAC;IAED,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC;IAChD,CAAC;IACD,IAAW,QAAQ,KAAI,OAAO,IAAI,CAAC,SAAS,CAAC,CAAA,CAAC;IACvC,OAAO;QACV,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED,IAAW,aAAa;QACpB,OAAO,IAAI,CAAC,sBAAsB,CAAC,aAAa,CAAC;IACrD,CAAC;IAEM,KAAK,CAAC,eAAe,CAAC,OAAkB;QAC3C,OAAO,IAAI,CAAC,YAAY,CACpB,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,OAAO,CAAC,EAChE,yBAAyB,CAC5B,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,EAAU;QAC5B,OAAO,IAAI,CAAC,YAAY,CACpB,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,EAAE,CAAC,EACpD,kBAAkB,CACrB,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"retryErrorsStorageAdapter.js","sourceRoot":"","sources":["../src/retryErrorsStorageAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAe/D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,OAAO,yBAAyB;IAElC,YACqB,sBAA+C,EAC/C,MAAwB;QADxB,2BAAsB,GAAtB,sBAAsB,CAAyB;QAC/C,WAAM,GAAN,MAAM,CAAkB;QAHrC,cAAS,GAAG,KAAK,CAAC;IAK1B,CAAC;IAED,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC;IAChD,CAAC;IACD,IAAW,QAAQ,KAAI,OAAO,IAAI,CAAC,SAAS,CAAC,CAAA,CAAC;IACvC,OAAO;QACV,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED,IAAW,aAAa;QACpB,OAAO,IAAI,CAAC,sBAAsB,CAAC,aAAa,CAAC;IACrD,CAAC;IAEM,KAAK,CAAC,eAAe,CAAC,OAAkB;QAC3C,OAAO,IAAI,CAAC,YAAY,CACpB,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,OAAO,CAAC,EAChE,yBAAyB,CAC5B,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,EAAU;QAC5B,OAAO,IAAI,CAAC,YAAY,CACpB,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,EAAE,CAAC,EACpD,kBAAkB,CACrB,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,SAAwB,EAAE,KAAa;QAC5D,OAAO,IAAI,CAAC,YAAY,CACpB,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,EACrE,qBAAqB,CACxB,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,KAAK,CAAC,IAAW,EAAE,OAAiB,EAAE,OAAe,EAAE,GAAW;QAC3E,OAAO,IAAI,CAAC,YAAY,CACpB,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAC1E,eAAe,CAClB,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,wBAAwB,CAAC,OAAqB,EAAE,OAAwB;QACjF,4DAA4D;QAC5D,OAAO,IAAI,CAAC,YAAY,CACpB,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,wBAAwB,CAAC,OAAO,EAAE,OAAO,CAAC,EAClF,kCAAkC,CACrC,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,eAAe,CAAC,MAAsB;QAC/C,OAAO,IAAI,CAAC,YAAY,CACpB,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,MAAM,CAAC,EAC/D,yBAAyB,CAC5B,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,UAAU,CAAC,IAAqB;QACzC,OAAO,IAAI,CAAC,YAAY,CACpB,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,IAAI,CAAC,EACxD,oBAAoB,CACvB,CAAC;IACN,CAAC;IAEO,oBAAoB;QACxB,IAAI,IAAI,CAAC,SAAS,EAAE;YAChB,MAAM,IAAI,YAAY,CAAC,mCAAmC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;SACpF;IACL,CAAC;IAEO,KAAK,CAAC,YAAY,CAAI,GAAqB,EAAE,QAAgB;QACjE,OAAO,YAAY,CACf,GAAG,EACH,QAAQ,EACR,IAAI,CAAC,MAAM,EACX,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,CACpC,CAAC;IACN,CAAC;CACJ","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { LoggingError } from \"@fluidframework/telemetry-utils\";\nimport {\n IDocumentStorageService,\n IDocumentStorageServicePolicies,\n ISummaryContext,\n} from \"@fluidframework/driver-definitions\";\nimport {\n ICreateBlobResponse,\n ISnapshotTree,\n ISummaryHandle,\n ISummaryTree,\n ITree,\n IVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { runWithRetry } from \"./retryUtils\";\n\nexport class RetryErrorsStorageAdapter implements IDocumentStorageService, IDisposable {\n private _disposed = false;\n constructor(\n private readonly internalStorageService: IDocumentStorageService,\n private readonly logger: ITelemetryLogger,\n ) {\n }\n\n public get policies(): IDocumentStorageServicePolicies | undefined {\n return this.internalStorageService.policies;\n }\n public get disposed() {return this._disposed;}\n public dispose() {\n this._disposed = true;\n }\n\n public get repositoryUrl(): string {\n return this.internalStorageService.repositoryUrl;\n }\n\n public async getSnapshotTree(version?: IVersion): Promise<ISnapshotTree | null> {\n return this.runWithRetry(\n async () => this.internalStorageService.getSnapshotTree(version),\n \"storage_getSnapshotTree\",\n );\n }\n\n public async readBlob(id: string): Promise<ArrayBufferLike> {\n return this.runWithRetry(\n async () => this.internalStorageService.readBlob(id),\n \"storage_readBlob\",\n );\n }\n\n public async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n return this.runWithRetry(\n async () => this.internalStorageService.getVersions(versionId, count),\n \"storage_getVersions\",\n );\n }\n\n public async write(tree: ITree, parents: string[], message: string, ref: string): Promise<IVersion> {\n return this.runWithRetry(\n async () => this.internalStorageService.write(tree, parents, message, ref),\n \"storage_write\",\n );\n }\n\n public async uploadSummaryWithContext(summary: ISummaryTree, context: ISummaryContext): Promise<string> {\n // Creation flow with attachment blobs - need to do retries!\n return this.runWithRetry(\n async () => this.internalStorageService.uploadSummaryWithContext(summary, context),\n \"storage_uploadSummaryWithContext\",\n );\n }\n\n public async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n return this.runWithRetry(\n async () => this.internalStorageService.downloadSummary(handle),\n \"storage_downloadSummary\",\n );\n }\n\n public async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n return this.runWithRetry(\n async () => this.internalStorageService.createBlob(file),\n \"storage_createBlob\",\n );\n }\n\n private checkStorageDisposed() {\n if (this._disposed) {\n throw new LoggingError(\"storageServiceDisposedCannotRetry\", { canRetry: false });\n }\n }\n\n private async runWithRetry<T>(api: () => Promise<T>, callName: string): Promise<T> {\n return runWithRetry(\n api,\n callName,\n this.logger,\n () => this.checkStorageDisposed(),\n );\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/odsp-driver",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.56.1",
|
|
4
4
|
"description": "Socket storage implementation for SPO and ODC",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": "https://github.com/microsoft/FluidFramework",
|
|
@@ -57,16 +57,16 @@
|
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
59
59
|
"@fluidframework/common-utils": "^0.32.1",
|
|
60
|
-
"@fluidframework/core-interfaces": "^0.
|
|
61
|
-
"@fluidframework/driver-base": "^0.
|
|
62
|
-
"@fluidframework/driver-definitions": "^0.
|
|
63
|
-
"@fluidframework/driver-utils": "^0.
|
|
60
|
+
"@fluidframework/core-interfaces": "^0.42.0",
|
|
61
|
+
"@fluidframework/driver-base": "^0.56.1",
|
|
62
|
+
"@fluidframework/driver-definitions": "^0.44.0",
|
|
63
|
+
"@fluidframework/driver-utils": "^0.56.1",
|
|
64
64
|
"@fluidframework/gitresources": "^0.1034.0",
|
|
65
|
-
"@fluidframework/odsp-doclib-utils": "^0.
|
|
66
|
-
"@fluidframework/odsp-driver-definitions": "^0.
|
|
65
|
+
"@fluidframework/odsp-doclib-utils": "^0.56.1",
|
|
66
|
+
"@fluidframework/odsp-driver-definitions": "^0.56.1",
|
|
67
67
|
"@fluidframework/protocol-base": "^0.1034.0",
|
|
68
68
|
"@fluidframework/protocol-definitions": "^0.1026.0",
|
|
69
|
-
"@fluidframework/telemetry-utils": "^0.
|
|
69
|
+
"@fluidframework/telemetry-utils": "^0.56.1",
|
|
70
70
|
"abort-controller": "^3.0.0",
|
|
71
71
|
"node-fetch": "^2.6.1",
|
|
72
72
|
"socket.io-client": "^2.4.0",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@fluidframework/build-common": "^0.23.0",
|
|
77
77
|
"@fluidframework/eslint-config-fluid": "^0.25.0",
|
|
78
|
-
"@fluidframework/mocha-test-setup": "^0.
|
|
78
|
+
"@fluidframework/mocha-test-setup": "^0.56.1",
|
|
79
79
|
"@microsoft/api-extractor": "^7.16.1",
|
|
80
80
|
"@rushstack/eslint-config": "^2.5.1",
|
|
81
81
|
"@types/mocha": "^8.2.2",
|
package/src/checkUrl.ts
CHANGED
|
@@ -27,7 +27,6 @@ export function checkUrl(documentUrl: URL): DriverPreCheckInfo | undefined {
|
|
|
27
27
|
} catch {}
|
|
28
28
|
|
|
29
29
|
return {
|
|
30
|
-
containerPath: locator.dataStorePath,
|
|
31
30
|
codeDetailsHint: locator?.containerPackageName,
|
|
32
31
|
// Add the snapshot endpoint, which has the same domain as the site URL
|
|
33
32
|
criticalBootDomains: siteOrigin ? [siteOrigin] : undefined,
|
package/src/contractsPublic.ts
CHANGED
|
@@ -22,7 +22,17 @@ export interface ISharingLinkHeader {
|
|
|
22
22
|
[SharingLinkHeader.isSharingLinkToRedeem]: boolean;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
export enum ClpCompliantAppHeader {
|
|
26
|
+
// Can be used in request made to resolver, to tell the resolver that the host app is CLP compliant.
|
|
27
|
+
// Odsp will not return Classified, labeled, or protected documents if the host app cannot support them.
|
|
28
|
+
isClpCompliantApp = "X-CLP-Compliant-App",
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface IClpCompliantAppHeader {
|
|
32
|
+
[ClpCompliantAppHeader.isClpCompliantApp]: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
25
35
|
declare module "@fluidframework/core-interfaces" {
|
|
26
36
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
27
|
-
export interface IRequestHeader extends Partial<ISharingLinkHeader> { }
|
|
37
|
+
export interface IRequestHeader extends Partial<ISharingLinkHeader>, Partial<IClpCompliantAppHeader> { }
|
|
28
38
|
}
|
package/src/createFile.ts
CHANGED
|
@@ -55,6 +55,7 @@ export async function createNewFluidFile(
|
|
|
55
55
|
epochTracker: EpochTracker,
|
|
56
56
|
fileEntry: IFileEntry,
|
|
57
57
|
createNewCaching: boolean,
|
|
58
|
+
forceAccessTokenViaAuthorizationHeader: boolean,
|
|
58
59
|
): Promise<IOdspResolvedUrl> {
|
|
59
60
|
// Check for valid filename before the request to create file is actually made.
|
|
60
61
|
if (isInvalidFileName(newFileInfo.filename)) {
|
|
@@ -67,10 +68,17 @@ export async function createNewFluidFile(
|
|
|
67
68
|
let sharingLink: string | undefined;
|
|
68
69
|
let sharingLinkErrorReason: string | undefined;
|
|
69
70
|
if (createNewSummary === undefined) {
|
|
70
|
-
itemId = await createNewEmptyFluidFile(
|
|
71
|
+
itemId = await createNewEmptyFluidFile(
|
|
72
|
+
getStorageToken, newFileInfo, logger, epochTracker, forceAccessTokenViaAuthorizationHeader);
|
|
71
73
|
} else {
|
|
72
74
|
const content = await createNewFluidFileFromSummary(
|
|
73
|
-
getStorageToken,
|
|
75
|
+
getStorageToken,
|
|
76
|
+
newFileInfo,
|
|
77
|
+
logger,
|
|
78
|
+
createNewSummary,
|
|
79
|
+
epochTracker,
|
|
80
|
+
forceAccessTokenViaAuthorizationHeader,
|
|
81
|
+
);
|
|
74
82
|
itemId = content.itemId;
|
|
75
83
|
summaryHandle = content.id;
|
|
76
84
|
sharingLink = content.sharingLink;
|
|
@@ -108,6 +116,7 @@ export async function createNewEmptyFluidFile(
|
|
|
108
116
|
newFileInfo: INewFileInfo,
|
|
109
117
|
logger: ITelemetryLogger,
|
|
110
118
|
epochTracker: EpochTracker,
|
|
119
|
+
forceAccessTokenViaAuthorizationHeader: boolean,
|
|
111
120
|
): Promise<string> {
|
|
112
121
|
const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : "";
|
|
113
122
|
// add .tmp extension to empty file (host is expected to rename)
|
|
@@ -123,7 +132,8 @@ export async function createNewEmptyFluidFile(
|
|
|
123
132
|
logger,
|
|
124
133
|
{ eventName: "createNewEmptyFile" },
|
|
125
134
|
async (event) => {
|
|
126
|
-
const { url, headers } = getUrlAndHeadersWithAuth(
|
|
135
|
+
const { url, headers } = getUrlAndHeadersWithAuth(
|
|
136
|
+
initialUrl, storageToken, forceAccessTokenViaAuthorizationHeader);
|
|
127
137
|
headers["Content-Type"] = "application/json";
|
|
128
138
|
|
|
129
139
|
const fetchResponse = await runWithRetry(
|
|
@@ -163,6 +173,7 @@ export async function createNewFluidFileFromSummary(
|
|
|
163
173
|
logger: ITelemetryLogger,
|
|
164
174
|
createNewSummary: ISummaryTree,
|
|
165
175
|
epochTracker: EpochTracker,
|
|
176
|
+
forceAccessTokenViaAuthorizationHeader: boolean,
|
|
166
177
|
): Promise<ICreateFileResponse> {
|
|
167
178
|
const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : "";
|
|
168
179
|
const encodedFilename = encodeURIComponent(newFileInfo.filename);
|
|
@@ -181,7 +192,8 @@ export async function createNewFluidFileFromSummary(
|
|
|
181
192
|
logger,
|
|
182
193
|
{ eventName: "createNewFile" },
|
|
183
194
|
async (event) => {
|
|
184
|
-
const { url, headers } = getUrlAndHeadersWithAuth(
|
|
195
|
+
const { url, headers } = getUrlAndHeadersWithAuth(
|
|
196
|
+
initialUrl, storageToken, forceAccessTokenViaAuthorizationHeader);
|
|
185
197
|
headers["Content-Type"] = "application/json";
|
|
186
198
|
|
|
187
199
|
const fetchResponse = await runWithRetry(
|
package/src/epochTracker.ts
CHANGED
|
@@ -18,13 +18,14 @@ import {
|
|
|
18
18
|
} from "@fluidframework/odsp-driver-definitions";
|
|
19
19
|
import { DriverErrorType } from "@fluidframework/driver-definitions";
|
|
20
20
|
import { PerformanceEvent, isFluidError, normalizeError } from "@fluidframework/telemetry-utils";
|
|
21
|
-
import { fetchAndParseAsJSONHelper, fetchArray, IOdspResponse } from "./odspUtils";
|
|
21
|
+
import { fetchAndParseAsJSONHelper, fetchArray, getOdspResolvedUrl, IOdspResponse } from "./odspUtils";
|
|
22
22
|
import {
|
|
23
23
|
IOdspCache,
|
|
24
24
|
INonPersistentCache,
|
|
25
25
|
IPersistedFileCache,
|
|
26
26
|
} from "./odspCache";
|
|
27
27
|
import { IVersionedValueWithEpoch, persistedCacheValueVersion } from "./contracts";
|
|
28
|
+
import { ClpCompliantAppHeader } from "./contractsPublic";
|
|
28
29
|
|
|
29
30
|
export type FetchType = "blob" | "createBlob" | "createFile" | "joinSession" | "ops" | "test" | "snapshotTree" |
|
|
30
31
|
"treesLatest" | "uploadSummary" | "push" | "versions";
|
|
@@ -170,8 +171,9 @@ export class EpochTracker implements IPersistedFileCache {
|
|
|
170
171
|
fetchOptions: RequestInit,
|
|
171
172
|
fetchType: FetchType,
|
|
172
173
|
addInBody: boolean = false,
|
|
174
|
+
fetchReason?: string,
|
|
173
175
|
): Promise<IOdspResponse<T>> {
|
|
174
|
-
const clientCorrelationId = this.formatClientCorrelationId();
|
|
176
|
+
const clientCorrelationId = this.formatClientCorrelationId(fetchReason);
|
|
175
177
|
// Add epoch in fetch request.
|
|
176
178
|
this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);
|
|
177
179
|
let epochFromResponse: string | undefined;
|
|
@@ -211,8 +213,9 @@ export class EpochTracker implements IPersistedFileCache {
|
|
|
211
213
|
fetchOptions: {[index: string]: any},
|
|
212
214
|
fetchType: FetchType,
|
|
213
215
|
addInBody: boolean = false,
|
|
216
|
+
fetchReason?: string,
|
|
214
217
|
) {
|
|
215
|
-
const clientCorrelationId = this.formatClientCorrelationId();
|
|
218
|
+
const clientCorrelationId = this.formatClientCorrelationId(fetchReason);
|
|
216
219
|
// Add epoch in fetch request.
|
|
217
220
|
this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);
|
|
218
221
|
let epochFromResponse: string | undefined;
|
|
@@ -245,12 +248,16 @@ export class EpochTracker implements IPersistedFileCache {
|
|
|
245
248
|
addInBody: boolean,
|
|
246
249
|
clientCorrelationId: string,
|
|
247
250
|
) {
|
|
251
|
+
const isClpCompliantApp = getOdspResolvedUrl(this.fileEntry.resolvedUrl).isClpCompliantApp;
|
|
248
252
|
if (addInBody) {
|
|
249
253
|
const headers: {[key: string]: string} = {};
|
|
250
254
|
headers["X-RequestStats"] = clientCorrelationId;
|
|
251
255
|
if (this.fluidEpoch !== undefined) {
|
|
252
256
|
headers["x-fluid-epoch"] = this.fluidEpoch;
|
|
253
257
|
}
|
|
258
|
+
if (isClpCompliantApp) {
|
|
259
|
+
headers[ClpCompliantAppHeader.isClpCompliantApp] = isClpCompliantApp.toString();
|
|
260
|
+
}
|
|
254
261
|
this.addParamInBody(fetchOptions, headers);
|
|
255
262
|
} else {
|
|
256
263
|
const addHeader = (key: string, val: string) => {
|
|
@@ -264,6 +271,9 @@ export class EpochTracker implements IPersistedFileCache {
|
|
|
264
271
|
if (this.fluidEpoch !== undefined) {
|
|
265
272
|
addHeader("x-fluid-epoch", this.fluidEpoch);
|
|
266
273
|
}
|
|
274
|
+
if (isClpCompliantApp) {
|
|
275
|
+
addHeader(ClpCompliantAppHeader.isClpCompliantApp, isClpCompliantApp.toString());
|
|
276
|
+
}
|
|
267
277
|
}
|
|
268
278
|
}
|
|
269
279
|
|
|
@@ -285,8 +295,12 @@ export class EpochTracker implements IPersistedFileCache {
|
|
|
285
295
|
fetchOptions.body = formParams.join("\r\n");
|
|
286
296
|
}
|
|
287
297
|
|
|
288
|
-
private formatClientCorrelationId() {
|
|
289
|
-
|
|
298
|
+
private formatClientCorrelationId(fetchReason?: string) {
|
|
299
|
+
const items: string[] = [`driverId=${this.driverId}`, `RequestNumber=${this.networkCallNumber++}`];
|
|
300
|
+
if (fetchReason !== undefined) {
|
|
301
|
+
items.push(`fetchReason=${fetchReason}`);
|
|
302
|
+
}
|
|
303
|
+
return items.join(", ");
|
|
290
304
|
}
|
|
291
305
|
|
|
292
306
|
protected validateEpochFromResponse(
|
|
@@ -395,13 +409,14 @@ export class EpochTrackerWithRedemption extends EpochTracker {
|
|
|
395
409
|
fetchOptions: {[index: string]: any},
|
|
396
410
|
fetchType: FetchType,
|
|
397
411
|
addInBody: boolean = false,
|
|
412
|
+
fetchReason?: string,
|
|
398
413
|
): Promise<IOdspResponse<T>> {
|
|
399
414
|
// Optimize the flow if we know that treesLatestDeferral was already completed by the timer we started
|
|
400
415
|
// joinSession call. If we did - there is no reason to repeat the call as it will fail with same error.
|
|
401
416
|
const completed = this.treesLatestDeferral.isCompleted;
|
|
402
417
|
|
|
403
418
|
try {
|
|
404
|
-
return await super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody);
|
|
419
|
+
return await super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody, fetchReason);
|
|
405
420
|
} catch (error) {
|
|
406
421
|
// Only handling here treesLatest. If createFile failed, we should never try to do joinSession.
|
|
407
422
|
// Similar, if getVersions failed, we should not do any further storage calls.
|
package/src/fetchSnapshot.ts
CHANGED
|
@@ -39,6 +39,7 @@ import { EpochTracker } from "./epochTracker";
|
|
|
39
39
|
* @param storageFetchWrapper - Implementation of the get/post methods used to fetch the snapshot
|
|
40
40
|
* @param versionId - id of specific snapshot to be fetched
|
|
41
41
|
* @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)
|
|
42
|
+
* @param forceAccessTokenViaAuthorizationHeader - whether to force passing given token via authorization header
|
|
42
43
|
* @returns A promise of the snapshot and the status code of the response
|
|
43
44
|
*/
|
|
44
45
|
export async function fetchSnapshot(
|
|
@@ -46,6 +47,7 @@ export async function fetchSnapshot(
|
|
|
46
47
|
token: string | null,
|
|
47
48
|
versionId: string,
|
|
48
49
|
fetchFullSnapshot: boolean,
|
|
50
|
+
forceAccessTokenViaAuthorizationHeader: boolean,
|
|
49
51
|
logger: ITelemetryLogger,
|
|
50
52
|
snapshotDownloader: (url: string, fetchOptions: {[index: string]: any}) => Promise<IOdspResponse<unknown>>,
|
|
51
53
|
): Promise<ISnapshotContents> {
|
|
@@ -61,7 +63,8 @@ export async function fetchSnapshot(
|
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
const queryString = getQueryString(queryParams);
|
|
64
|
-
const { url, headers } = getUrlAndHeadersWithAuth(
|
|
66
|
+
const { url, headers } = getUrlAndHeadersWithAuth(
|
|
67
|
+
`${snapshotUrl}${path}${queryString}`, token, forceAccessTokenViaAuthorizationHeader);
|
|
65
68
|
const response = await PerformanceEvent.timedExecAsync(
|
|
66
69
|
logger,
|
|
67
70
|
{
|
|
@@ -77,6 +80,7 @@ export async function fetchSnapshotWithRedeem(
|
|
|
77
80
|
odspResolvedUrl: IOdspResolvedUrl,
|
|
78
81
|
storageTokenFetcher: InstrumentedStorageTokenFetcher,
|
|
79
82
|
snapshotOptions: ISnapshotOptions | undefined,
|
|
83
|
+
forceAccessTokenViaAuthorizationHeader: boolean,
|
|
80
84
|
logger: ITelemetryLogger,
|
|
81
85
|
snapshotDownloader: (
|
|
82
86
|
finalOdspResolvedUrl: IOdspResolvedUrl,
|
|
@@ -88,6 +92,12 @@ export async function fetchSnapshotWithRedeem(
|
|
|
88
92
|
removeEntries: () => Promise<void>,
|
|
89
93
|
enableRedeemFallback?: boolean,
|
|
90
94
|
): Promise<ISnapshotContents> {
|
|
95
|
+
// back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51
|
|
96
|
+
const sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;
|
|
97
|
+
if(sharingLinkToRedeem) {
|
|
98
|
+
odspResolvedUrl.shareLinkInfo = {...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem}
|
|
99
|
+
}
|
|
100
|
+
|
|
91
101
|
return fetchLatestSnapshotCore(
|
|
92
102
|
odspResolvedUrl,
|
|
93
103
|
storageTokenFetcher,
|
|
@@ -103,16 +113,15 @@ export async function fetchSnapshotWithRedeem(
|
|
|
103
113
|
eventName: "RedeemFallback",
|
|
104
114
|
errorType: error.errorType,
|
|
105
115
|
}, error);
|
|
106
|
-
await redeemSharingLink(
|
|
116
|
+
await redeemSharingLink(
|
|
117
|
+
odspResolvedUrl, storageTokenFetcher, logger, forceAccessTokenViaAuthorizationHeader);
|
|
107
118
|
const odspResolvedUrlWithoutShareLink: IOdspResolvedUrl =
|
|
108
|
-
{ ...odspResolvedUrl,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
sharingLinkToRedeem: undefined,
|
|
119
|
+
{ ...odspResolvedUrl,
|
|
120
|
+
shareLinkInfo: {
|
|
121
|
+
...odspResolvedUrl.shareLinkInfo,
|
|
122
|
+
sharingLinkToRedeem: undefined
|
|
123
|
+
}
|
|
114
124
|
};
|
|
115
|
-
}
|
|
116
125
|
|
|
117
126
|
return fetchLatestSnapshotCore(
|
|
118
127
|
odspResolvedUrlWithoutShareLink,
|
|
@@ -141,6 +150,7 @@ async function redeemSharingLink(
|
|
|
141
150
|
odspResolvedUrl: IOdspResolvedUrl,
|
|
142
151
|
storageTokenFetcher: InstrumentedStorageTokenFetcher,
|
|
143
152
|
logger: ITelemetryLogger,
|
|
153
|
+
forceAccessTokenViaAuthorizationHeader: boolean,
|
|
144
154
|
) {
|
|
145
155
|
return PerformanceEvent.timedExecAsync(
|
|
146
156
|
logger,
|
|
@@ -148,12 +158,13 @@ async function redeemSharingLink(
|
|
|
148
158
|
eventName: "RedeemShareLink",
|
|
149
159
|
},
|
|
150
160
|
async () => getWithRetryForTokenRefresh(async (tokenFetchOptions) => {
|
|
151
|
-
assert(!!odspResolvedUrl.sharingLinkToRedeem,
|
|
161
|
+
assert(!!odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,
|
|
152
162
|
0x1ed /* "Share link should be present" */);
|
|
153
163
|
const storageToken = await storageTokenFetcher(tokenFetchOptions, "RedeemShareLink");
|
|
154
|
-
const encodedShareUrl = getEncodedShareUrl(odspResolvedUrl.sharingLinkToRedeem);
|
|
164
|
+
const encodedShareUrl = getEncodedShareUrl(odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem);
|
|
155
165
|
const redeemUrl = `${odspResolvedUrl.siteUrl}/_api/v2.0/shares/${encodedShareUrl}`;
|
|
156
|
-
const { url, headers } = getUrlAndHeadersWithAuth(
|
|
166
|
+
const { url, headers } = getUrlAndHeadersWithAuth(
|
|
167
|
+
redeemUrl, storageToken, forceAccessTokenViaAuthorizationHeader);
|
|
157
168
|
headers.prefer = "redeemSharingLink";
|
|
158
169
|
return fetchAndParseAsJSONHelper(url, { headers });
|
|
159
170
|
}),
|
|
@@ -189,7 +200,7 @@ async function fetchLatestSnapshotCore(
|
|
|
189
200
|
const perfEvent = {
|
|
190
201
|
eventName: "TreesLatest",
|
|
191
202
|
attempts: tokenFetchOptions.refresh ? 2 : 1,
|
|
192
|
-
shareLinkPresent: odspResolvedUrl.sharingLinkToRedeem !== undefined,
|
|
203
|
+
shareLinkPresent: odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined,
|
|
193
204
|
redeemFallbackEnabled: enableRedeemFallback,
|
|
194
205
|
};
|
|
195
206
|
if (snapshotOptions !== undefined) {
|
|
@@ -423,8 +434,8 @@ function getFormBodyAndHeaders(
|
|
|
423
434
|
}
|
|
424
435
|
});
|
|
425
436
|
}
|
|
426
|
-
if (odspResolvedUrl.sharingLinkToRedeem) {
|
|
427
|
-
formParams.push(`sl: ${odspResolvedUrl.sharingLinkToRedeem}`);
|
|
437
|
+
if (odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem) {
|
|
438
|
+
formParams.push(`sl: ${odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem}`);
|
|
428
439
|
}
|
|
429
440
|
formParams.push(`_post: 1`);
|
|
430
441
|
formParams.push(`\r\n--${formBoundary}--`);
|
|
@@ -467,6 +478,12 @@ export async function downloadSnapshot(
|
|
|
467
478
|
controller?: AbortController,
|
|
468
479
|
epochTracker?: EpochTracker,
|
|
469
480
|
): Promise<ISnapshotRequestAndResponseOptions> {
|
|
481
|
+
// back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51
|
|
482
|
+
const sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;
|
|
483
|
+
if(sharingLinkToRedeem) {
|
|
484
|
+
odspResolvedUrl.shareLinkInfo = {...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem}
|
|
485
|
+
}
|
|
486
|
+
|
|
470
487
|
if (fetchBinarySnapshotFormat) {
|
|
471
488
|
// Logging an event here as it is not supposed to be used in production yet and only in experimental mode.
|
|
472
489
|
logger.sendTelemetryEvent({ eventName: "BinarySnapshotFetched" });
|
|
@@ -477,7 +494,7 @@ export async function downloadSnapshot(
|
|
|
477
494
|
}
|
|
478
495
|
|
|
479
496
|
function isRedeemSharingLinkError(odspResolvedUrl: IOdspResolvedUrl, error: any) {
|
|
480
|
-
if (odspResolvedUrl.sharingLinkToRedeem !== undefined
|
|
497
|
+
if (odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined
|
|
481
498
|
&& (typeof error === "object" && error !== null)
|
|
482
499
|
&& (error.errorType === DriverErrorType.authorizationError
|
|
483
500
|
|| error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError)) {
|
package/src/getFileLink.ts
CHANGED
|
@@ -84,7 +84,7 @@ async function getFileLinkCore(
|
|
|
84
84
|
identityType: IdentityType,
|
|
85
85
|
logger: ITelemetryLogger,
|
|
86
86
|
): Promise<string> {
|
|
87
|
-
const fileItem = await getFileItemLite(getToken, odspUrlParts, logger);
|
|
87
|
+
const fileItem = await getFileItemLite(getToken, odspUrlParts, logger, identityType === "Consumer");
|
|
88
88
|
|
|
89
89
|
// ODC canonical link does not require any additional processing
|
|
90
90
|
if (identityType === "Consumer") {
|
|
@@ -104,7 +104,10 @@ async function getFileLinkCore(
|
|
|
104
104
|
const { url, headers } = getUrlAndHeadersWithAuth(
|
|
105
105
|
`${odspUrlParts.siteUrl}/_api/web/GetFileByUrl(@a1)/ListItemAllFields/GetSharingInformation?@a1=${
|
|
106
106
|
encodeURIComponent(`'${fileItem.webDavUrl}'`)
|
|
107
|
-
}`,
|
|
107
|
+
}`,
|
|
108
|
+
tokenFromResponse(token),
|
|
109
|
+
false,
|
|
110
|
+
);
|
|
108
111
|
const requestInit = {
|
|
109
112
|
method: "POST",
|
|
110
113
|
headers: {
|
|
@@ -152,6 +155,7 @@ async function getFileItemLite(
|
|
|
152
155
|
getToken: TokenFetcher<OdspResourceTokenFetchOptions>,
|
|
153
156
|
odspUrlParts: IOdspUrlParts,
|
|
154
157
|
logger: ITelemetryLogger,
|
|
158
|
+
forceAccessTokenViaAuthorizationHeader: boolean,
|
|
155
159
|
): Promise<FileItemLite> {
|
|
156
160
|
return PerformanceEvent.timedExecAsync(
|
|
157
161
|
logger,
|
|
@@ -166,6 +170,7 @@ async function getFileItemLite(
|
|
|
166
170
|
const { url, headers } = getUrlAndHeadersWithAuth(
|
|
167
171
|
`${siteUrl}/_api/v2.0/drives/${driveId}/items/${itemId}?select=webUrl,webDavUrl`,
|
|
168
172
|
tokenFromResponse(token),
|
|
173
|
+
forceAccessTokenViaAuthorizationHeader,
|
|
169
174
|
);
|
|
170
175
|
const requestInit = { method: "GET", headers };
|
|
171
176
|
const response = await fetchHelper(url, requestInit);
|
|
@@ -3,48 +3,34 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const queryParamStart = url.indexOf("?");
|
|
12
|
-
|
|
13
|
-
if (queryParamStart === -1) {
|
|
14
|
-
return 0;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return url.length - queryParamStart - 1;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// eslint-disable-next-line max-len
|
|
21
|
-
export function getUrlAndHeadersWithAuth(url: string, token: string | null): { url: string, headers: { [index: string]: string } } {
|
|
6
|
+
export function getUrlAndHeadersWithAuth(
|
|
7
|
+
url: string,
|
|
8
|
+
token: string | null,
|
|
9
|
+
forceAccessTokenViaAuthorizationHeader: boolean,
|
|
10
|
+
): { url: string, headers: { [index: string]: string } } {
|
|
22
11
|
if (!token || token.length === 0) {
|
|
23
12
|
return { url, headers: {} };
|
|
24
13
|
}
|
|
25
14
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
headers: {},
|
|
46
|
-
url: url + tokenQueryParam,
|
|
47
|
-
};
|
|
15
|
+
if (!forceAccessTokenViaAuthorizationHeader) {
|
|
16
|
+
// Pass access token via query string: this will make request be treated as 'simple' request
|
|
17
|
+
// which does not require OPTIONS call as part of CORS check.
|
|
18
|
+
const urlWithAccessTokenInQueryString = new URL(url);
|
|
19
|
+
// IMPORTANT: Do not apply encodeURIComponent to token, param value is automatically encoded
|
|
20
|
+
// when set via URLSearchParams class
|
|
21
|
+
urlWithAccessTokenInQueryString.searchParams.set("access_token", token);
|
|
22
|
+
// ODSP APIs have a limitation that the query string cannot exceed 2048 characters.
|
|
23
|
+
// If the query string exceeds 2048, we have to fall back to sending the access token as a header, which
|
|
24
|
+
// has a negative performance implication as it adds a performance overhead.
|
|
25
|
+
// NOTE: URL.search.length value includes '?' symbol and it is unclear whether backend logic which enforces
|
|
26
|
+
// query length limit accounts for it. This logic errs on side of caution and includes that key in overall
|
|
27
|
+
// query length.
|
|
28
|
+
if (urlWithAccessTokenInQueryString.search.length <= 2048) {
|
|
29
|
+
return {
|
|
30
|
+
headers: {},
|
|
31
|
+
url: urlWithAccessTokenInQueryString.href,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
48
34
|
}
|
|
49
35
|
|
|
50
36
|
return {
|
|
@@ -53,9 +53,6 @@ export class OdspDeltaStorageService {
|
|
|
53
53
|
let postBody = `--${formBoundary}\r\n`;
|
|
54
54
|
postBody += `Authorization: Bearer ${storageToken}\r\n`;
|
|
55
55
|
postBody += `X-HTTP-Method-Override: GET\r\n`;
|
|
56
|
-
if (fetchReason !== undefined) {
|
|
57
|
-
postBody += `fetchReason: ${fetchReason}\r\n`;
|
|
58
|
-
}
|
|
59
56
|
|
|
60
57
|
postBody += `_post: 1\r\n`;
|
|
61
58
|
postBody += `\r\n--${formBoundary}--`;
|
|
@@ -81,6 +78,7 @@ export class OdspDeltaStorageService {
|
|
|
81
78
|
},
|
|
82
79
|
"ops",
|
|
83
80
|
true,
|
|
81
|
+
fetchReason,
|
|
84
82
|
);
|
|
85
83
|
clearTimeout(timer);
|
|
86
84
|
const deltaStorageResponse = response.content;
|
|
@@ -104,6 +104,7 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
104
104
|
cacheAndTracker.epochTracker,
|
|
105
105
|
fileEntry,
|
|
106
106
|
this.hostPolicy.cacheCreateNewSummary ?? true,
|
|
107
|
+
!!this.hostPolicy.sessionOptions?.forceAccessTokenViaAuthorizationHeader,
|
|
107
108
|
);
|
|
108
109
|
const docService = this.createDocumentServiceCore(odspResolvedUrl, odspLogger, cacheAndTracker);
|
|
109
110
|
event.end({
|