fleet/frontend/pages/SoftwarePage/SoftwareAddPage/helpers.tsx
Martin Angers 915408c2a8
IPA: validate conflicts with other installers, return proper error (#38005)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #36621

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)

## Testing

- [x] Added/updated automated tests
- [x] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [x] QA'd all new/changed functionality manually
See
https://github.com/fleetdm/fleet/issues/36621#issuecomment-3740340604

---------

Co-authored-by: Jonathan Katz <44128041+jkatz01@users.noreply.github.com>
Co-authored-by: Carlo DiCelico <carlo@fleetdm.com>
2026-01-13 10:30:03 -05:00

51 lines
1.9 KiB
TypeScript

import React from "react";
export const ADD_SOFTWARE_ERROR_PREFIX = "Couldn't add.";
export const DEFAULT_ADD_SOFTWARE_ERROR_MESSAGE = `${ADD_SOFTWARE_ERROR_PREFIX} Please try again.`;
export const REQUEST_TIMEOUT_ERROR_MESSAGE = `${ADD_SOFTWARE_ERROR_PREFIX} Request timeout. Please make sure your server and load balancer timeout is long enough.`;
/**
* Ensures that a string ends with a period.
* If the string is empty or already ends with a period, it is returned unchanged.
*/
export const ensurePeriod = (str: string) => {
if (str && !str.endsWith(".")) {
return `${str}.`;
}
return str;
};
/**
* Matches API messages after the fixed Couldn't add software. prefix,
* and renders just the part about what is available for install.
* Returns a formatted React element if matched; otherwise, returns null. */
export const formatAlreadyAvailableInstallMessage = (msg: string) => {
// Remove prefix (with or without trailing space)
const cleaned = msg.replace(/^Couldn't add software\.?\s*/, "");
// New regex for "<package> already has an installer available for the <team> team."
const installerExistsRegex = /^(.+?) already.+the (.+?) team\./;
let match = cleaned.match(installerExistsRegex);
if (match) {
return (
<>
{ADD_SOFTWARE_ERROR_PREFIX} <b>{match[1]}</b> already has an installer
available for the <b>{match[2]}</b> team.{" "}
</>
);
}
// New regex for "SoftwareInstaller <package> already exists with team <team>."
// or "In-house app <package> already exists with team <team>."
const packageExistsRegex = /^(?:SoftwareInstaller|In-house app) "(.+?)" already.+ team "(.+?)"\./;
match = cleaned.match(packageExistsRegex);
if (match) {
return (
<>
{ADD_SOFTWARE_ERROR_PREFIX} <b>{match[1]}</b> already has an installer
available for the <b>{match[2]}</b> team.{" "}
</>
);
}
return null;
};