From 7fcc4899afebd965ec0d433a2caa52ea8fbd09f5 Mon Sep 17 00:00:00 2001 From: Harrison Ravazzolo <38767391+harrisonravazzolo@users.noreply.github.com> Date: Tue, 18 Nov 2025 19:02:21 -0800 Subject: [PATCH] macOS FMA: Canva (#35884) **Related issue:** Resolves # # Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] 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. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [ ] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [ ] Added/updated automated tests - [ ] 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) - [ ] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [ ] Confirmed that the fix is not expected to adversely impact load test results - [ ] Alerted the release DRI if additional load testing is needed ## Database migrations - [ ] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [ ] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [ ] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`). ## New Fleet configuration settings - [ ] Setting(s) is/are explicitly excluded from GitOps If you didn't check the box above, follow this checklist for GitOps-enabled settings: - [ ] Verified that the setting is exported via `fleetctl generate-gitops` - [ ] Verified the setting is documented in a separate PR to [the GitOps documentation](https://github.com/fleetdm/fleet/blob/main/docs/Configuration/yaml-files.md#L485) - [ ] Verified that the setting is cleared on the server if it is not supplied in a YAML file (or that it is documented as being optional) - [ ] Verified that any relevant UI is disabled when GitOps mode is enabled ## fleetd/orbit/Fleet Desktop - [ ] Verified compatibility with the latest released version of Fleet (see [Must rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md)) - [ ] If the change applies to only one platform, confirmed that `runtime.GOOS` is used as needed to isolate changes - [ ] Verified that fleetd runs on macOS, Linux and Windows - [ ] Verified auto-update works from the released version of component to the new version (see [tools/tuf/test](../tools/tuf/test/README.md)) --------- Co-authored-by: Allen Houchins <32207388+allenhouchins@users.noreply.github.com> Co-authored-by: Allen Houchins --- ee/maintained-apps/inputs/homebrew/canva.json | 8 +++++++ ee/maintained-apps/outputs/apps.json | 7 ++++++ ee/maintained-apps/outputs/canva/darwin.json | 21 ++++++++++++++++++ .../SoftwarePage/components/icons/Canva.tsx | 14 ++++++++++++ .../assets/images/app-icon-canva-60x60@2x.png | Bin 0 -> 17004 bytes 5 files changed, 50 insertions(+) create mode 100644 ee/maintained-apps/inputs/homebrew/canva.json create mode 100644 ee/maintained-apps/outputs/canva/darwin.json create mode 100644 frontend/pages/SoftwarePage/components/icons/Canva.tsx create mode 100644 website/assets/images/app-icon-canva-60x60@2x.png diff --git a/ee/maintained-apps/inputs/homebrew/canva.json b/ee/maintained-apps/inputs/homebrew/canva.json new file mode 100644 index 0000000000..74d2d99fde --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/canva.json @@ -0,0 +1,8 @@ +{ + "name": "Canva", + "unique_identifier": "com.canva.CanvaDesktop", + "token": "canva", + "installer_format": "dmg", + "slug": "canva/darwin", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/outputs/apps.json b/ee/maintained-apps/outputs/apps.json index 3db64904bb..007a82dd0c 100644 --- a/ee/maintained-apps/outputs/apps.json +++ b/ee/maintained-apps/outputs/apps.json @@ -78,6 +78,13 @@ "unique_identifier": "Brave", "description": "Brave is a web browser designed with privacy, blocking ads and trackers by default while maintaining fast speed." }, + { + "name": "Canva", + "slug": "canva/darwin", + "platform": "darwin", + "unique_identifier": "com.canva.CanvaDesktop", + "description": "Canva is a popular online graphic design tool." + }, { "name": "ChatGPT Desktop", "slug": "chatgpt/darwin", diff --git a/ee/maintained-apps/outputs/canva/darwin.json b/ee/maintained-apps/outputs/canva/darwin.json new file mode 100644 index 0000000000..80392afdc6 --- /dev/null +++ b/ee/maintained-apps/outputs/canva/darwin.json @@ -0,0 +1,21 @@ +{ + "versions": [ + { + "version": "1.119.0", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.canva.CanvaDesktop';" + }, + "installer_url": "https://desktop-release.canva.com/Canva-1.119.0-universal.dmg", + "install_script_ref": "11c0a042", + "uninstall_script_ref": "b93d994d", + "sha256": "b66f268478c5ed9b87f82cb71ee564d6dfdea2defce82a88664a65bd3fa8c02c", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "11c0a042": "#!/bin/sh\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath $INSTALLER_PATH)\")\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n if ! osascript -e \"application id \\\"$bundle_id\\\" is running\" 2\u003e/dev/null; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ $EUID -eq 0 \u0026\u0026 \"$console_user\" == \"root\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS \u003c timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" \u003e/dev/null 2\u003e\u00261; then\n if ! pgrep -f \"$bundle_id\" \u003e/dev/null 2\u003e\u00261; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nhdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\"\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\"\n# copy to the applications folder\nquit_application 'com.canva.CanvaDesktop'\nif [ -d \"$APPDIR/Canva.app\" ]; then\n\tsudo mv \"$APPDIR/Canva.app\" \"$TMPDIR/Canva.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Canva.app\" \"$APPDIR\"\n", + "b93d994d": "#!/bin/sh\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil \u003c\u003c\u003c \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Canva.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Canva'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.canva.CanvaDesktop'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.canva.CanvaDesktop.ShipIt'\ntrash $LOGGED_IN_USER '~/Library/LaunchAgents/com.canva.availability-check-agent.plist'\ntrash $LOGGED_IN_USER '~/Library/Logs/Canva'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.canva.CanvaDesktop.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.canva.CanvaDesktop.savedState'\n" + } +} \ No newline at end of file diff --git a/frontend/pages/SoftwarePage/components/icons/Canva.tsx b/frontend/pages/SoftwarePage/components/icons/Canva.tsx new file mode 100644 index 0000000000..39e192a498 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Canva.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Canva = (props: SVGProps) => ( + + + +); +export default Canva; diff --git a/website/assets/images/app-icon-canva-60x60@2x.png b/website/assets/images/app-icon-canva-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..bcf6b9ca9730256dc1c05ca7fcfa39feaa80b14d GIT binary patch literal 17004 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