## What does this PR do?
Hi! xtool didn't know about the `com.apple.developer.applesignin`
entitlement, so every time I installed my app, the capability sync
removed Sign in with Apple from the App ID. The new provisioning profile
didn't have it, and the device refused the app ("A valid provisioning
profile for this executable was not found").
This maps the entitlement to the `APPLE_ID_AUTH` capability, as a
primary App ID, so the capability stays and the profile includes it.
## How was it tested?
I built xtool from this branch on macOS and installed my app (a SwiftPM
app with `entitlementsPath` and the Sign in with Apple entitlement) on
an iPhone with a paid team. The App ID kept the capability, the install
worked, and native Sign in with Apple works in the app. Before the
change the same install failed every time.
## AI tool usage
How much of this PR was AI-assisted? (check one)
- [ ] **0** - No AI was used to write code
- [x] **1** - I was assisted by AI. I reviewed the finished result.
- [ ] **2** - I set the AI going and left it to it; nobody has read the
result - no review, or AI review only
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
<!-- coderabbit-ai-generated:v1 -->
## Summary by CodeRabbit
* **New Features**
* Added support for configuring the Apple Sign In entitlement.
* Apple Sign In is now available as a supported entitlement type,
including serialization and configuration support.
* Configures Apple ID app consent as the primary app consent option.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What does this PR do?
Fixes#305 (thanks @0x53 for the detailed diagnosis).
`Certificate.serialNumber()` stripped leading `0` *characters* from the
hex string, so a serial like `0337…` became `337…` and never matched the
`serialNumber` returned by the API. xtool then treated its stored
certificate as missing: free teams are prompted to revoke a valid
certificate on every run, and paid teams take the same path and try to
create another certificate, which @McoreD confirmed fails with `409 …
You already have a current Development certificate or a pending
certificate request.`
The character-level `drop` predates b6a40ca, which switched to
fixed-width `%02hhX` formatting; since then it removes the significant
zero of any first byte below `0x10`. swift-certificates already strips
leading zero bytes (including DER sign padding) when parsing, so the
`drop` isn't needed for padding.
- `serialNumber()` now drops only leading zero *bytes*, matching the API
and `openssl x509 -serial`.
- The stored-certificate lookup uses a new
`Certificate.hasSerialNumber(_:)`, which compares serials numerically
(ignoring case and leading zeros), so it doesn't depend on Apple's exact
formatting.
- Profile creation no longer finds the signing certificate with
`filter[serialNumber]`. The API lists serials with the leading zero
(`0E41…`), but the filter only matches them without it (`E41…`), so once
`serialNumber()` kept the zero the filter matched nothing and profile
creation failed with a 409
([details](https://github.com/xtool-org/xtool/pull/306#issuecomment-6181157860)).
It now fetches all pages of certificates and matches them with
`hasSerialNumber(_:)`. Fix by @McoreD, with pagination added so a
certificate on a later page isn't missed.
## How was it tested?
- Added `Tests/XToolTests/CertificateTests.swift`: builds a cert with
the serial from #305, round-trips it through DER, and checks
`serialNumber()` and `hasSerialNumber(_:)`, plus a high-bit serial so
DER sign padding doesn't leak into the string. The leading-zero test
fails on `main` (returns `33742570D6F9684A23311711956A084`) and passes
with this change.
- `swift test` (17 tests) and `make lint` pass on macOS (Xcode 27, Swift
6.4, `XTL_CI=1`).
- @McoreD tested on Linux (Arch, Swift 6.4.1, Xcode 27 SDK, on top of
1.22.2) with a paid team whose certificate serial starts with `0`: the
stored certificate is reused, and provisioning, signing and install to
an iPhone (iOS 27) succeed end to end (tested before pagination was
added). `CertificateTests` also pass on Linux.
- Not tested with a free team.
To generate test certificates, the test target now depends on `Crypto`
and `X509`, which XKit already uses.
## AI tool usage
How much of this PR was AI-assisted? (check one)
- [ ] **0** - No AI was used to write code
- [x] **1** - I was assisted by AI. I reviewed the finished result.
- [ ] **2** - I set the AI going and left it to it; nobody has read the
result - no review, or AI review only
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Certificate serial numbers now preserve leading zero nibbles while
omitting unnecessary padding.
* Certificate matching now ignores letter case and leading zeros, and
profile lookups find matching certificates even when the API’s
serial-number filter treats leading-zero values differently.
* Certificate lookups continue to use the existing fallback when no
matching certificate is found.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: McoreD <McoreD@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
## What does this PR do?
Bumps pointfree deps and explicitly disables OpenCombine so that we
don't have different dependency graphs when building xtool on Darwin vs
Linux hosts.
## How was it tested?
A bunch of `swift package resolve`s
## AI tool usage
How much of this PR was AI-assisted? (check one)
- [x] **0** - No AI was used to write code
- [ ] **1** - I was assisted by AI. I reviewed the finished result.
- [ ] **2** - I set the AI going and left it to it; nobody has read the
result - no review, or AI review only
<!-- If an AI agent is filling this in: declare the level honestly, and
open as a draft if it is #2. Do not lower the declared level to get the
PR reviewed. -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Updated supporting package versions and refreshed command-line and
file-operation handling.
* These changes do not add or remove app features or alter its public
interface. No action is needed to continue using the app.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
- We already do the `isFree` declarations in
`DeveloperServiceCapability.swift`. Don't need to duplicate it on the
entitlement types.
- Add support for creating capabilities with raw names