mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-30 23:34:27 +00:00
fix(ui): show Registry subscription and setup prompts (#13038)
This commit is contained in:
1 parent
286ae6c7cf
commit
64c19b3db6
23 files changed
+571
-73
No files matched your search
@@ -190,6 +190,9 @@ export async function classifyRegistryFailure(
|
||||
endpoint: RegistryEndpoint,
|
||||
credentialStatus: RegistryCredentialStatus | null,
|
||||
): Promise<RegistryFailureResult> {
|
||||
if (response.status === 402) {
|
||||
return { status: REGISTRY_FAILURE.SUBSCRIPTION_REQUIRED };
|
||||
}
|
||||
if (response.status === 401 || response.status === 403) {
|
||||
return { status: REGISTRY_FAILURE.ACCESS_DENIED };
|
||||
}
|
||||
@@ -198,15 +201,16 @@ export async function classifyRegistryFailure(
|
||||
return { status: REGISTRY_FAILURE.ERROR };
|
||||
}
|
||||
|
||||
const code = await getRegistryErrorCode(response);
|
||||
if (
|
||||
response.status === 409 &&
|
||||
credentialStatus !== null &&
|
||||
!isActiveRegistryCredential(credentialStatus)
|
||||
(code === "registry_credential_not_configured" ||
|
||||
(credentialStatus !== null &&
|
||||
!isActiveRegistryCredential(credentialStatus)))
|
||||
) {
|
||||
return { status: REGISTRY_FAILURE.ONBOARDING };
|
||||
}
|
||||
|
||||
const code = await getRegistryErrorCode(response);
|
||||
if (response.status === 502 && code === REGISTRY_ERROR_CODE.KEY_REJECTED) {
|
||||
return { status: REGISTRY_FAILURE.RECONNECT };
|
||||
}
|
||||
|
||||
@@ -115,6 +115,45 @@ function mockRequestDeadlines() {
|
||||
}
|
||||
|
||||
describe("installed Registry provider discovery", () => {
|
||||
it("reports a missing Registry key as setup rather than a connection failure", async () => {
|
||||
// Given
|
||||
mockDiscovery({
|
||||
failedEndpoint: "providers",
|
||||
failureStatus: 409,
|
||||
failureBody: { errors: [{ code: "registry_credential_not_configured" }] },
|
||||
});
|
||||
|
||||
// When / Then
|
||||
expect(await getInstalledRegistryProviderOptions()).toEqual({
|
||||
status: "onboarding",
|
||||
});
|
||||
});
|
||||
|
||||
it("shows the paywall when bootstrapping Registry requires a subscription", async () => {
|
||||
// Given
|
||||
fetchMock.mockResolvedValueOnce(jsonResponse({}, 402));
|
||||
|
||||
// When / Then
|
||||
expect(await getRegistryBootstrap()).toEqual({
|
||||
status: "subscription_required",
|
||||
});
|
||||
expect(fetchMock).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it.each(["available-artifacts", "artifacts", "providers"])(
|
||||
"offers a paid plan when the %s read requires a subscription",
|
||||
async (failedEndpoint) => {
|
||||
// Given
|
||||
mockDiscovery({ failedEndpoint, failureStatus: 402 });
|
||||
|
||||
// When
|
||||
const result = await getInstalledRegistryProviderOptions();
|
||||
|
||||
// Then
|
||||
expect(result).toEqual({ status: "subscription_required" });
|
||||
},
|
||||
);
|
||||
|
||||
function mockDiscovery({
|
||||
emptyMetadata = false,
|
||||
failedEndpoint,
|
||||
|
||||
@@ -138,6 +138,8 @@ async function classifyDiscoveryFailure(
|
||||
credential: RegistryCredentialStatus | null,
|
||||
) {
|
||||
if (response.status === 409 && credential === null) {
|
||||
const failure = await classifyRegistryFailure(response, endpoint, null);
|
||||
if (failure.status === REGISTRY_FAILURE.ONBOARDING) return failure;
|
||||
const currentCredential = await readRegistryCredential(accessToken);
|
||||
if (currentCredential.status === REGISTRY_FAILURE.ACCESS_DENIED) {
|
||||
return currentCredential;
|
||||
@@ -211,6 +213,18 @@ export async function getInstalledRegistryProviderOptions(): Promise<RegistryPro
|
||||
)
|
||||
)
|
||||
return { status: REGISTRY_PROVIDER_DISCOVERY.ACCESS_DENIED };
|
||||
if (
|
||||
[catalog.status, installed.status, providers.status].some(
|
||||
(status) => status === REGISTRY_FAILURE.SUBSCRIPTION_REQUIRED,
|
||||
)
|
||||
)
|
||||
return { status: REGISTRY_PROVIDER_DISCOVERY.SUBSCRIPTION_REQUIRED };
|
||||
if (
|
||||
[catalog.status, providers.status].some(
|
||||
(status) => status === REGISTRY_FAILURE.ONBOARDING,
|
||||
)
|
||||
)
|
||||
return { status: REGISTRY_PROVIDER_DISCOVERY.ONBOARDING };
|
||||
if (
|
||||
catalog.status !== REGISTRY_CATALOG.COMPLETE ||
|
||||
installed.status !== "ready" ||
|
||||
@@ -303,8 +317,11 @@ function bootstrapReady(
|
||||
function bootstrapFailure(
|
||||
failure: RegistryFailureResult,
|
||||
): RegistryBootstrapResult {
|
||||
if (failure.status === REGISTRY_FAILURE.ACCESS_DENIED) {
|
||||
return { status: REGISTRY_FAILURE.ACCESS_DENIED };
|
||||
if (
|
||||
failure.status === REGISTRY_FAILURE.ACCESS_DENIED ||
|
||||
failure.status === REGISTRY_FAILURE.SUBSCRIPTION_REQUIRED
|
||||
) {
|
||||
return { status: failure.status };
|
||||
}
|
||||
return bootstrapReady({
|
||||
status:
|
||||
@@ -340,8 +357,11 @@ export async function getRegistryBootstrap(): Promise<RegistryBootstrapResult> {
|
||||
}
|
||||
|
||||
const catalog = await readCompleteRegistryCatalog(access, credential);
|
||||
if (catalog.status === REGISTRY_FAILURE.ACCESS_DENIED) {
|
||||
return { status: REGISTRY_FAILURE.ACCESS_DENIED };
|
||||
if (
|
||||
catalog.status === REGISTRY_FAILURE.ACCESS_DENIED ||
|
||||
catalog.status === REGISTRY_FAILURE.SUBSCRIPTION_REQUIRED
|
||||
) {
|
||||
return { status: catalog.status };
|
||||
}
|
||||
if (catalog.status === REGISTRY_CATALOG.INCOMPLETE) {
|
||||
return bootstrapReady({
|
||||
|
||||
Reference in new issue
Block a user