diff --git a/src/Common/Constants.ts b/src/Common/Constants.ts index 860c74317..9da0ab448 100644 --- a/src/Common/Constants.ts +++ b/src/Common/Constants.ts @@ -351,6 +351,7 @@ export class HttpStatusCodes { public static readonly Created: number = 201; public static readonly Accepted: number = 202; public static readonly NoContent: number = 204; + public static readonly NotModified: number = 304; public static readonly Unauthorized: number = 401; public static readonly Forbidden: number = 403; public static readonly NotFound: number = 404; diff --git a/src/Contracts/DataModels.ts b/src/Contracts/DataModels.ts index 5ef3a8094..85b767204 100644 --- a/src/Contracts/DataModels.ts +++ b/src/Contracts/DataModels.ts @@ -437,10 +437,8 @@ export interface Tenant { export interface AccountKeys { primaryMasterKey: string; secondaryMasterKey: string; - properties: { - primaryReadonlyMasterKey: string; - secondaryReadonlyMasterKey: string; - }; + primaryReadonlyMasterKey: string; + secondaryReadonlyMasterKey: string; } export interface AfecFeature { diff --git a/src/Platform/Hosted/ArmResourceUtils.ts b/src/Platform/Hosted/ArmResourceUtils.ts index 7731fb01d..038854343 100644 --- a/src/Platform/Hosted/ArmResourceUtils.ts +++ b/src/Platform/Hosted/ArmResourceUtils.ts @@ -123,10 +123,18 @@ export abstract class ArmResourceUtils { try { const fetchHeaders = await ArmResourceUtils._getAuthHeader(ArmResourceUtils._armAuthArea, tenantId); - const url = `${ArmResourceUtils._armEndpoint}/${cosmosdbResourceId}/listKeys?api-version=${Constants.ArmApiVersions.documentDB}`; - - const response: Response = await fetch(url, { headers: fetchHeaders, method: "POST" }); - const result: AccountKeys = response.status === 204 || response.status === 304 ? null : await response.json(); + const readWriteKeysUrl = `${ArmResourceUtils._armEndpoint}/${cosmosdbResourceId}/listKeys?api-version=${Constants.ArmApiVersions.documentDB}`; + const readOnlyKeysUrl = `${ArmResourceUtils._armEndpoint}/${cosmosdbResourceId}/readOnlyKeys?api-version=${Constants.ArmApiVersions.documentDB}`; + let response: Response = await fetch(readWriteKeysUrl, { headers: fetchHeaders, method: "POST" }); + if (response.status === Constants.HttpStatusCodes.Forbidden) { + // fetch read only keys for readers + response = await fetch(readOnlyKeysUrl, { headers: fetchHeaders, method: "POST" }); + } + const result: AccountKeys = + response.status === Constants.HttpStatusCodes.NoContent || + response.status === Constants.HttpStatusCodes.NotModified + ? null + : await response.json(); if (!response.ok) { throw result; } diff --git a/src/Platform/Hosted/Main.ts b/src/Platform/Hosted/Main.ts index a7f83163c..78fc7129a 100644 --- a/src/Platform/Hosted/Main.ts +++ b/src/Platform/Hosted/Main.ts @@ -568,8 +568,9 @@ export default class Main { this._explorer.hideConnectExplorerForm(); + const masterKey = Main._getMasterKey(keys); HostedExplorerFactory.reInitializeDocumentClientUtilityForExplorer(this._explorer); - Main._setExplorerReady(this._explorer, keys.primaryMasterKey, account, authorizationToken); + Main._setExplorerReady(this._explorer, masterKey, account, authorizationToken); } private static _handleGetAccessAadSucceed(response: [DatabaseAccount, AccountKeys, string]) { @@ -577,12 +578,21 @@ export default class Main { return; } const account = response[0]; - const keys = response[1]; + const masterKey = Main._getMasterKey(response[1]); const authorizationToken = response[2]; - Main._setExplorerReady(this._explorer, keys.primaryMasterKey, account, authorizationToken); + Main._setExplorerReady(this._explorer, masterKey, account, authorizationToken); this._getAadAccessDeferred.resolve(this._explorer); } + private static _getMasterKey(keys: AccountKeys): string { + return ( + keys?.primaryMasterKey ?? + keys?.secondaryMasterKey ?? + keys?.primaryReadonlyMasterKey ?? + keys?.secondaryReadonlyMasterKey + ); + } + private static _handleGetAccessAadFailed(error: any) { this._getAadAccessDeferred.reject(error); }