{
 "app_id": "me.proton.Pass",
 "source_url": "https://raw.githubusercontent.com/flathub/me.proton.Pass/master/me.proton.Pass.yml",
 "runtime": "org.freedesktop.Platform",
 "runtime_version": "25.08",
 "sdk": "org.freedesktop.Sdk",
 "finish_args": [
  "--share=ipc",
  "--share=network",
  "--socket=wayland",
  "--socket=x11",
  "--device=all",
  "--filesystem=xdg-run/Clipboard",
  "--talk-name=org.kde.StatusNotifierWatcher",
  "--talk-name=org.freedesktop.secrets"
 ],
 "module_count": 3,
 "fetched_at": "2026-09-17T16:13:11.862287+00:00",
 "manifest": {
  "app-id": "me.proton.Pass",
  "runtime": "org.freedesktop.Platform",
  "runtime-version": "25.08",
  "sdk": "org.freedesktop.Sdk",
  "base": "org.electronjs.Electron2.BaseApp",
  "base-version": "25.08",
  "sdk-extensions": [
   "org.freedesktop.Sdk.Extension.node22",
   "org.freedesktop.Sdk.Extension.rust-stable"
  ],
  "command": "start-proton-pass",
  "finish-args": [
   "--share=ipc",
   "--share=network",
   "--socket=wayland",
   "--socket=x11",
   "--filesystem=xdg-run/Clipboard",
   "--device=all",
   "--talk-name=org.freedesktop.secrets",
   "--talk-name=org.kde.StatusNotifierWatcher",
   "--env=XCURSOR_PATH=~/.icons:/app/share/icons:/icons:/run/host/user-share/icons:/run/host/share/icons"
  ],
  "modules": [
   {
    "name": "dbus-run-session",
    "buildsystem": "cmake-ninja",
    "cleanup": [
     "*"
    ],
    "sources": [
     {
      "type": "archive",
      "url": "https://gitlab.freedesktop.org/dbus/dbus/-/archive/dbus-1.16.2/dbus-dbus-1.16.2.tar.gz",
      "sha256": "d77cc71acd93e85f2bd2a6fe3a40e5bd023519e3e9fa9b5361e7109f42b74060",
      "x-checker-data": {
       "type": "anitya",
       "project-id": 5356,
       "url-template": "https://gitlab.freedesktop.org/dbus/dbus/-/archive/dbus-$version/dbus-dbus-$version.tar.gz"
      }
     }
    ]
   },
   {
    "name": "libsecret",
    "buildsystem": "meson",
    "config-opts": [
     "-Dmanpage=false",
     "-Dcrypto=disabled",
     "-Dvapi=false",
     "-Dgtk_doc=false",
     "-Dintrospection=false",
     "-Dbash_completion=disabled"
    ],
    "cleanup": [
     "/bin",
     "/include",
     "/lib/pkgconfig",
     "/share/man"
    ],
    "sources": [
     {
      "type": "archive",
      "url": "https://download.gnome.org/sources/libsecret/0.21/libsecret-0.21.8.2.tar.xz",
      "sha256": "142948339c5b971d8f6a8c7099521f6fd319b6fe73d2694b4e6d3310ed28b6e6",
      "x-checker-data": {
       "type": "gnome",
       "name": "libsecret",
       "stable-only": true
      }
     }
    ]
   },
   {
    "name": "proton-pass",
    "buildsystem": "simple",
    "build-options": {
     "append-path": "/usr/lib/sdk/node22/bin:/usr/lib/sdk/rust-stable/bin",
     "env": {
      "HOME": "/run/build/proton-pass",
      "CI": "true",
      "SENTRY_CLI_SKIP_DOWNLOAD": "1",
      "YARN_ENABLE_IMMUTABLE_INSTALLS": "0",
      "RUSTUP_HOME": "/usr/lib/sdk/rust-stable",
      "CARGO_HOME": "/run/build/proton-pass/cargo",
      "CARGO_NET_OFFLINE": "true",
      "FLATPAK_ELECTRON_ZIP_DIR": "/run/build/proton-pass/flatpak-node/cache/electron",
      "YARN_ENABLE_NETWORK": "0",
      "YARN_ENABLE_TELEMETRY": "0",
      "YARN_ENABLE_INLINE_BUILDS": "1",
      "YARN_ENABLE_GLOBAL_CACHE": "0",
      "YARN_GLOBAL_FOLDER": "/run/build/proton-pass/flatpak-node/yarn-berry",
      "XDG_CACHE_HOME": "/run/build/proton-pass/flatpak-node/cache",
      "npm_config_nodedir": "/usr/lib/sdk/node22",
      "NODE_ENV": "production"
     }
    },
    "build-commands": [
     "python3 -c \"\nimport re, pathlib\ntext = pathlib.Path('.yarnrc.yml').read_text()\nfor pat in [\n  r'^plugins:\\n([ \\t]+.*\\n)*',\n  r'^npmPublishRegistry:.*\\n(\\n)?',\n  r'^npmScopes:\\n([ \\t]+.*\\n)*',\n  r'^npmPreapprovedPackages:\\n([ \\t]+.*\\n)*',\n  r'^npmMinimalAgeGate:.*\\n',\n]:\n  text = re.sub(pat, '', text, flags=re.MULTILINE)\npathlib.Path('.yarnrc.yml').write_text(text)\n\"\n",
     "node -e \"\n  const fs = require('fs');\n  const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));\n  pkg.workspaces = pkg.workspaces\n    .filter(w => w !== 'applications/*' && !w.startsWith('tests'))\n    .filter(w => !w.startsWith('applications/') ||\n                 w === 'applications/pass-desktop/native' ||\n                 w === 'applications/pass' ||\n                 w === 'applications/pass-desktop')\n    .concat(['applications/pass', 'applications/pass-desktop']);\n  pkg.workspaces = [...new Set(pkg.workspaces)];\n  fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\\n');\n\"\n",
     "node -e \"\n  const fs = require('fs');\n  const path = require('path');\n  const glob = (dir, results=[]) => {\n    for (const f of fs.readdirSync(dir, {withFileTypes: true})) {\n      const full = path.join(dir, f.name);\n      if (f.isDirectory() && f.name !== 'node_modules' && f.name !== '.git') glob(full, results);\n      else if (f.name === 'package.json') results.push(full);\n    }\n    return results;\n  };\n  const cwd = process.cwd();\n  // Load root package.json workspaces list to only count active workspaces\n  const rootPkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf8'));\n  const workspaces = rootPkg.workspaces || [];\n  const matchWorkspace = (pattern, relDir) => {\n    const patternParts = pattern.split('/');\n    const pathParts = relDir.split(path.sep);\n    if (patternParts.length !== pathParts.length) return false;\n    for (let i = 0; i < patternParts.length; i++) {\n      if (patternParts[i] === '*') continue;\n      if (patternParts[i] !== pathParts[i]) return false;\n    }\n    return true;\n  };\n  // Build the set of package names actually present in the repo tree and active in workspaces.\n  const wsNames = new Set();\n  for (const p of glob(cwd)) {\n    try {\n      const relDir = path.relative(cwd, path.dirname(p));\n      const isWs = workspaces.some(w => matchWorkspace(w, relDir));\n      if (isWs) {\n        const d = JSON.parse(fs.readFileSync(p,'utf8'));\n        if (d.name) wsNames.add(d.name);\n      }\n    } catch {}\n  }\n  // Private npm scopes unreachable from the offline sandbox.\n  const privateRe = /^(@proton-meet\\/|@tpe\\/)|^@proton\\/proton-foundation-search\\$/;\n  let totalRemoved = 0;\n  for (const p of glob(cwd)) {\n    try {\n      const pkg = JSON.parse(fs.readFileSync(p,'utf8'));\n      let changed = false;\n      for (const sec of ['dependencies','devDependencies','peerDependencies']) {\n        for (const dep of Object.keys(pkg[sec] || {})) {\n          const ver = pkg[sec][dep];\n          // Workspace protocol has two forms:\n          //   Path-based: workspace:some/path  \u2014 Yarn resolves by path, not dep name.\n          //     Phantom only if the target path does not exist in the repo.\n          //   Name-based: workspace:^, workspace:*, workspace:~, workspace:1.x\n          //     Phantom if the dep name is not the 'name' field of any package.json.\n          let isPhantomWs = false;\n          if (ver.startsWith('workspace:')) {\n            const wsSpec = ver.slice('workspace:'.length);\n            if (wsSpec.includes('/')) {\n              isPhantomWs = !fs.existsSync(path.join(cwd, wsSpec));\n            } else {\n              isPhantomWs = !wsNames.has(dep);\n            }\n          }\n          const isPrivateNpm = privateRe.test(dep);\n          if (isPhantomWs || isPrivateNpm) {\n            const rel = path.relative(cwd, p);\n            console.log('Removing [' + (isPhantomWs?'phantom ws':'private npm') + '] ' + dep + ' from ' + rel);\n            delete pkg[sec][dep];\n            changed = true;\n            totalRemoved++;\n          }\n        }\n      }\n      if (changed) fs.writeFileSync(p, JSON.stringify(pkg, null, 2) + '\\n');\n    } catch(e) { /* skip unreadable */ }\n  }\n  console.log('Done: removed ' + totalRemoved + ' unresolvable dep(s).');\n\"\n",
     "bash flatpak-node/setup_sdk_node_headers.sh",
     "yarn plugin import $FLATPAK_BUILDER_BUILDDIR/flatpak-node/flatpak-yarn.js",
     "yarn convertToZip $(which yarn)",
     "yarn install --mode=skip-build",
     "mkdir -p applications/pass-desktop/native/.cargo\ncat > applications/pass-desktop/native/.cargo/config.toml << 'CARGOEOF'\n[source.crates-io]\nreplace-with = \"vendored-sources\"\n\n[source.vendored-sources]\ndirectory = \"/run/build/proton-pass/cargo/vendor\"\nCARGOEOF\n",
     "cd applications/pass-desktop && yarn run build:native",
     "EHASH=41a5d68646d956d50e13830e121ea0b3d6ab378b6a0ce422aefc1ff214707879\nECACHE=flatpak-node/cache/electron\nmkdir -p \"$ECACHE/$EHASH\"\ncase \"$FLATPAK_ARCH\" in\n  aarch64) EZIP=\"electron-v39.8.10-linux-arm64.zip\" ;;\n  *)       EZIP=\"electron-v39.8.10-linux-x64.zip\"   ;;\nesac\ncp \"$ECACHE/$EZIP\" \"$ECACHE/$EHASH/$EZIP\" || true\ncp \"$ECACHE/SHASUMS256.txt-39.8.10\" \"$ECACHE/$EHASH/SHASUMS256.txt\" || true\n",
     "cd applications/pass-desktop && yarn exec -- electron-forge package",
     "case \"$FLATPAK_ARCH\" in\n  aarch64) ELECTRON_ARCH=\"arm64\" ;;\n  arm)     ELECTRON_ARCH=\"armv7l\" ;;\n  *)       ELECTRON_ARCH=\"x64\" ;;\nesac\ncp -r \"applications/pass-desktop/out/Proton Pass-linux-${ELECTRON_ARCH}\" \"${FLATPAK_DEST}/proton-pass\"\n",
     "for lang in ${FLATPAK_DEST}/proton-pass/locales/*.pak\ndo\n  locale=\"$(basename -s .pak $lang)\"\n  install -Dm644 -t \"${FLATPAK_DEST}/share/runtime/locale/${locale%%-*}/\" \"$lang\"\n  ln -sf \"${FLATPAK_DEST}/share/runtime/locale/${locale%%-*}/$(basename $lang)\" \"${FLATPAK_DEST}/proton-pass/locales/$(basename $lang)\"\ndone\n",
     "install -Dm644 applications/pass-desktop/assets/logo.svg \"${FLATPAK_DEST}/share/icons/hicolor/scalable/apps/${FLATPAK_ID}.svg\"",
     "install -Dm644 me.proton.Pass.desktop \"${FLATPAK_DEST}/share/applications/${FLATPAK_ID}.desktop\"",
     "patch-electron-desktop-filename \"${FLATPAK_DEST}/proton-pass/resources/app.asar\"",
     "install -Dm644 me.proton.Pass.metainfo.xml \"${FLATPAK_DEST}/share/metainfo/${FLATPAK_ID}.metainfo.xml\"",
     "install -Dm644 LICENSE \"${FLATPAK_DEST}/share/licenses/${FLATPAK_ID}/LICENSE\"",
     "install -Dm755 start-proton-pass.sh /app/bin/start-proton-pass"
    ],
    "sources": [
     {
      "type": "git",
      "url": "https://github.com/ProtonMail/WebClients.git",
      "tag": "proton-pass@1.40.2",
      "commit": "49d318ed19e7fff27057ad2631a024a99e619250",
      "x-checker-data": {
       "type": "json",
       "url": "https://proton.me/download/PassDesktop/linux/x64/version.json",
       "version-query": ".Releases | map(select(.CategoryName == \"Stable\")) | .[0].Version",
       "tag-query": "\"proton-pass@\" + (.Releases | map(select(.CategoryName == \"Stable\")) | .[0].Version)"
      }
     },
     "generated-sources.json",
     "cargo-sources.json",
     {
      "type": "patch",
      "path": "fix-native-build.patch"
     },
     {
      "type": "patch",
      "path": "fix-forge-electron-cache.patch"
     },
     {
      "type": "file",
      "path": "me.proton.Pass.desktop"
     },
     {
      "type": "file",
      "path": "me.proton.Pass.metainfo.xml"
     },
     {
      "type": "script",
      "dest-filename": "start-proton-pass.sh",
      "commands": [
       "env TMPDIR=\"$XDG_RUNTIME_DIR/app/${FLATPAK_ID:-me.proton.Pass}\" zypak-wrapper \"/app/proton-pass/Proton Pass\" \"$@\""
      ]
     }
    ]
   }
  ]
 }
}