Fix unreleased bug: API error message for duplicate VPP apps (#20808)

This commit is contained in:
Sarah Gillespie 2024-07-29 15:46:27 -05:00 committed by GitHub
parent 275a09e361
commit 53ba476516
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 33 additions and 2 deletions

View file

@ -5,12 +5,22 @@ const ADD_SOFTWARE_ERROR_PREFIX = "Couldnt add software.";
const DEFAULT_ERROR_MESSAGE = `${ADD_SOFTWARE_ERROR_PREFIX} Please try again.`;
const generateAlreadyAvailableMessage = (msg: string) => {
// This regex matches the API message where the title already has a software package (non-VPP) available for install.
const regex = new RegExp(
`${ADD_SOFTWARE_ERROR_PREFIX} (.+) already.+on the (.+) team.`
);
const match = msg.match(regex);
if (!match) return DEFAULT_ERROR_MESSAGE;
if (!match) {
if (msg.includes("VPPApp")) {
// This is the case where someone already added this VPP app. This should almost never happen
// because we omit apps that are already available from the list in the UI, but just in case of
// shenanigans with concurrent requests or something, we'll handle it with a generic message.
// The list should clear itself up on the next page load.
return `${ADD_SOFTWARE_ERROR_PREFIX} The software is already available to install on this team.`;
}
return DEFAULT_ERROR_MESSAGE;
}
return (
<>

View file

@ -11,7 +11,7 @@ export interface IVppApp {
name: string;
icon_url: string;
latest_version: string;
app_store_id: number;
app_store_id: number; // FIXME: This seems to be coming back as a string but we're not seeing TS errors because there's an implicit any cast
added: boolean;
platform: string; // "darwin" | "ios" | "ipados"
}
@ -68,6 +68,9 @@ export default {
},
addVppApp: (teamId: number, appStoreId: number) => {
// FIXME: API seems to expect app_store_id to be a string but we're not seeing TS errors because
// there's an implicit any cast on getVppApps response that is being fed into the appStoreId
// param (so it's being treated as a number even though it is really a string being passed in here)
const { MDM_APPLE_VPP_APPS } = endpoints;
return sendRequest("POST", MDM_APPLE_VPP_APPS, {
app_store_id: appStoreId,

View file

@ -288,6 +288,13 @@ VALUES
}
_, err := tx.ExecContext(ctx, stmt, adamID, globalOrTmID, teamID)
if IsDuplicate(err) {
err = &existsError{
Identifier: adamID,
TeamID: teamID,
ResourceType: "VPPAppAdamID",
}
}
return ctxerr.Wrap(ctx, err, "writing vpp app team mapping to db")
}

View file

@ -62,6 +62,12 @@ func testVPPAppMetadata(t *testing.T, ds *Datastore) {
require.NoError(t, err)
require.Equal(t, &fleet.VPPAppStoreApp{Name: "vpp1", AppStoreID: vpp1}, meta)
// try to add the same app again, fails
var existsErr *existsError
_, err = ds.InsertVPPAppWithTeam(ctx, &fleet.VPPApp{Name: "vpp1", BundleIdentifier: "com.app.vpp1", AdamID: "adam_vpp_app_1"}, nil)
require.Error(t, err)
require.ErrorAs(t, err, &existsErr)
// create team1 app
va2, err := ds.InsertVPPAppWithTeam(ctx, &fleet.VPPApp{Name: "vpp2", BundleIdentifier: "com.app.vpp2", AdamID: "adam_vpp_app_2"}, &team1.ID)
require.NoError(t, err)
@ -72,6 +78,11 @@ func testVPPAppMetadata(t *testing.T, ds *Datastore) {
require.NoError(t, err)
require.Equal(t, &fleet.VPPAppStoreApp{Name: "vpp2", AppStoreID: vpp2}, meta)
// try to add the same app again, fails
_, err = ds.InsertVPPAppWithTeam(ctx, &fleet.VPPApp{Name: "vpp2", BundleIdentifier: "com.app.vpp2", AdamID: "adam_vpp_app_2"}, &team1.ID)
require.Error(t, err)
require.ErrorAs(t, err, &existsErr)
// get it for team 2, does not exist
meta, err = ds.GetVPPAppMetadataByTeamAndTitleID(ctx, &team2.ID, titleID2)
require.Error(t, err)