mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(mobile/ios): align Apple app identities
Co-authored-by: Tom Brow <tomb@block.xyz> Signed-off-by: Tom Brow <tomb@block.xyz>
This commit is contained in:
co-authored by
Tom Brow
parent
737457569a
commit
4f86c6cbc5
@@ -24,6 +24,13 @@
|
||||
| `BUZZ_PUSH_GRANT_KEYS` | Capability AEAD keyring, `id:base64-32-bytes[,predecessor...]`; current key first. |
|
||||
| `BUZZ_PUSH_TOKEN_KEYS` | Independent token-custody AEAD keyring in the same format. Never reuse grant keys. |
|
||||
|
||||
Each gateway deployment represents exactly one Apple team and bundle-id pair:
|
||||
`BUZZ_PUSH_APP_ATTEST_APP_ID` and `BUZZ_PUSH_APNS_TOPIC` are scalar startup
|
||||
settings, and the mounted APNs certificate must match that topic. Dogfood
|
||||
(`JMTDPW9CG3` / `xyz.block.buzz.dogfood.mobile`) and production
|
||||
(`EYF346PHUG` / `xyz.block.buzz.mobile`) therefore require separate gateway
|
||||
deployments with their own matching settings and credentials.
|
||||
|
||||
Optional endpoint quota policy variables are `BUZZ_PUSH_ENDPOINT_QUOTA_WINDOW_SECONDS` (default `10`, max `86400`) and `BUZZ_PUSH_ENDPOINT_QUOTA_MAX_DELIVERIES` (default `10`, max `10000`). These are Buzz policy hypotheses, not Apple-published limits; tune under load while retaining a hard ceiling.
|
||||
|
||||
## Secret and key rotation rules
|
||||
|
||||
+2
-1
@@ -22,7 +22,8 @@ cd mobile && flutter run
|
||||
### Worktree-aware debug identity
|
||||
|
||||
Debug builds produced from a git worktree get a unique app identifier keyed
|
||||
to the **worktree directory name** (`com.buzz.buzzMobile.<slug>` on iOS,
|
||||
to the **worktree directory name**
|
||||
(`xyz.block.buzz.dogfood.mobile.<slug>` on iOS,
|
||||
`xyz.block.buzz.mobile.<slug>` on Android) plus a display-only branch label
|
||||
in the app name (`Buzz (my-branch)`, or a short SHA when the worktree is
|
||||
detached). Because the identifier follows the directory rather than the
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// without patching tracked files by writing
|
||||
// `mobile/ios/Flutter/AppOverrides.xcconfig` containing
|
||||
// `BUNDLE_IDENTIFIER = your.app.id` (gitignored).
|
||||
BUNDLE_IDENTIFIER = com.buzz.buzzMobile
|
||||
BUNDLE_IDENTIFIER = xyz.block.buzz.dogfood.mobile
|
||||
APP_DISPLAY_NAME = Buzz
|
||||
BUZZ_APP_GROUP_IDENTIFIER = group.$(BUNDLE_IDENTIFIER)
|
||||
BUZZ_KEYCHAIN_ACCESS_GROUP = $(BUNDLE_IDENTIFIER)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// Defaults for the iOS Release build. Internal/custom builds (e.g. an
|
||||
// enterprise-signed distribution) override these without patching tracked
|
||||
// files by writing `mobile/ios/Flutter/AppOverrides.xcconfig` (gitignored).
|
||||
BUNDLE_IDENTIFIER = com.buzz.buzzMobile
|
||||
BUNDLE_IDENTIFIER = xyz.block.buzz.mobile
|
||||
APP_DISPLAY_NAME = Buzz
|
||||
CODE_SIGN_STYLE = Automatic
|
||||
CODE_SIGN_IDENTITY = iPhone Developer
|
||||
|
||||
@@ -631,7 +631,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DEVELOPMENT_TEAM = EYF346PHUG;
|
||||
ENABLE_BITCODE = NO;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
@@ -820,7 +820,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DEVELOPMENT_TEAM = JMTDPW9CG3;
|
||||
ENABLE_BITCODE = NO;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
@@ -844,7 +844,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DEVELOPMENT_TEAM = EYF346PHUG;
|
||||
ENABLE_BITCODE = NO;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
@@ -867,7 +867,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DEVELOPMENT_TEAM = JMTDPW9CG3;
|
||||
GENERATE_INFOPLIST_FILE = NO;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
@@ -891,7 +891,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DEVELOPMENT_TEAM = EYF346PHUG;
|
||||
GENERATE_INFOPLIST_FILE = NO;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
@@ -915,7 +915,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
DEVELOPMENT_TEAM = EYF346PHUG;
|
||||
GENERATE_INFOPLIST_FILE = NO;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>$(BUZZ_IOS_PUSH_ENVIRONMENT)</string>
|
||||
<key>com.apple.developer.app-attest.environment</key>
|
||||
<key>com.apple.developer.devicecheck.appattest-environment</key>
|
||||
<string>$(BUZZ_APP_ATTEST_ENVIRONMENT)</string>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
# Uninstalls stale worktree-suffixed Buzz debug builds from booted iOS
|
||||
# simulators and connected Android devices/emulators. Production installs
|
||||
# (com.buzz.buzzMobile / xyz.block.buzz.mobile, no suffix) are never touched:
|
||||
# only identifiers with a worktree suffix appended after the production id
|
||||
# are matched. Run `just mobile-clean` (or this script directly); pass
|
||||
# --dry-run to list what would be removed without uninstalling.
|
||||
# simulators and connected Android devices/emulators. Unsuffixed app installs
|
||||
# (`xyz.block.buzz.dogfood.mobile` and `xyz.block.buzz.mobile`) are never
|
||||
# touched. Only identifiers with a worktree suffix appended after the dogfood
|
||||
# or production id are matched. Run `just mobile-clean` (or this script
|
||||
# directly); pass --dry-run to list what would be removed without uninstalling.
|
||||
set -euo pipefail
|
||||
|
||||
ios_prefix="com.buzz.buzzMobile."
|
||||
ios_prefix="xyz.block.buzz.dogfood.mobile."
|
||||
android_prefix="xyz.block.buzz.mobile."
|
||||
|
||||
dry_run=0
|
||||
|
||||
@@ -70,7 +70,7 @@ case "$android_slug" in
|
||||
[0-9]*) android_slug="w_$android_slug" ;;
|
||||
esac
|
||||
|
||||
ios_bundle_id="com.buzz.buzzMobile.${ios_slug}"
|
||||
ios_bundle_id="xyz.block.buzz.dogfood.mobile.${ios_slug}"
|
||||
android_suffix=".${android_slug}"
|
||||
|
||||
cat > "$ios_overrides" <<XCCONFIG
|
||||
|
||||
@@ -63,7 +63,7 @@ out="$("$wt/scripts/mobile-worktree-overrides.sh")"
|
||||
ios="$wt/mobile/ios/Flutter/WorktreeOverrides.xcconfig"
|
||||
android="$wt/mobile/android/worktree.properties"
|
||||
[[ -f "$ios" && -f "$android" ]] || fail "worktree must write both override files"
|
||||
grep -q '^BUNDLE_IDENTIFIER = com\.buzz\.buzzMobile\.feature-work-1$' "$ios" \
|
||||
grep -q '^BUNDLE_IDENTIFIER = xyz\.block\.buzz\.dogfood\.mobile\.feature-work-1$' "$ios" \
|
||||
&& pass "iOS bundle identifier keys to the sanitized worktree directory name" \
|
||||
|| fail "iOS bundle identifier must key to the worktree dir, got: $(cat "$ios")"
|
||||
grep -q '^APP_DISPLAY_NAME = Buzz (Fix_Thing-2)$' "$ios" \
|
||||
@@ -82,7 +82,7 @@ printf '%s' "$out" | grep -q 'Worktree Feature_Work-1' \
|
||||
# ── Branch switch in the same worktree: identity stable, label follows ───────
|
||||
git -C "$wt" checkout -q -b "another/branch-name"
|
||||
"$wt/scripts/mobile-worktree-overrides.sh" > /dev/null
|
||||
grep -q '^BUNDLE_IDENTIFIER = com\.buzz\.buzzMobile\.feature-work-1$' "$ios" \
|
||||
grep -q '^BUNDLE_IDENTIFIER = xyz\.block\.buzz\.dogfood\.mobile\.feature-work-1$' "$ios" \
|
||||
&& grep -q '^applicationIdSuffix=\.feature_work_1$' "$android" \
|
||||
&& pass "branch switch keeps the install identity stable (per worktree)" \
|
||||
|| fail "install identity must not change on branch switch"
|
||||
@@ -122,10 +122,15 @@ grep -q '^applicationIdSuffix=\.w_2fast$' "$wt2/mobile/android/worktree.properti
|
||||
# ── Tracked build files: overrides are debug-only, release stays production ──
|
||||
debug_xcconfig="$repo_root/mobile/ios/Flutter/Debug.xcconfig"
|
||||
release_xcconfig="$repo_root/mobile/ios/Flutter/Release.xcconfig"
|
||||
pbxproj="$repo_root/mobile/ios/Runner.xcodeproj/project.pbxproj"
|
||||
runner_entitlements="$repo_root/mobile/ios/Runner/Runner.entitlements"
|
||||
gradle="$repo_root/mobile/android/app/build.gradle.kts"
|
||||
manifest="$repo_root/mobile/android/app/src/main/AndroidManifest.xml"
|
||||
plist="$repo_root/mobile/ios/Runner/Info.plist"
|
||||
|
||||
grep -q '^BUNDLE_IDENTIFIER = xyz\.block\.buzz\.dogfood\.mobile$' "$debug_xcconfig" \
|
||||
&& pass "Debug.xcconfig defaults to the dogfood bundle identifier" \
|
||||
|| fail "Debug.xcconfig must default to xyz.block.buzz.dogfood.mobile"
|
||||
grep -q 'WorktreeOverrides.xcconfig' "$debug_xcconfig" \
|
||||
&& pass "Debug.xcconfig includes WorktreeOverrides" \
|
||||
|| fail "Debug.xcconfig must include WorktreeOverrides.xcconfig"
|
||||
@@ -136,15 +141,57 @@ if [[ -n "$worktree_line" && -n "$app_line" && "$worktree_line" -lt "$app_line"
|
||||
else
|
||||
fail "Debug.xcconfig must include AppOverrides.xcconfig after WorktreeOverrides.xcconfig"
|
||||
fi
|
||||
grep -q '^ios_prefix="xyz.block.buzz.dogfood.mobile\."$' "$clean_script" \
|
||||
&& pass "cleanup targets the iOS dogfood worktree prefix" \
|
||||
|| fail "cleanup must share the iOS dogfood prefix used by worktree overrides"
|
||||
|
||||
grep -q 'WorktreeOverrides' "$release_xcconfig" \
|
||||
&& fail "Release.xcconfig must not include WorktreeOverrides.xcconfig" \
|
||||
|| pass "Release.xcconfig does not include WorktreeOverrides"
|
||||
grep -q '^BUNDLE_IDENTIFIER = com\.buzz\.buzzMobile$' "$release_xcconfig" \
|
||||
grep -q '^BUNDLE_IDENTIFIER = xyz\.block\.buzz\.mobile$' "$release_xcconfig" \
|
||||
&& pass "Release.xcconfig keeps the production bundle identifier" \
|
||||
|| fail "Release.xcconfig must keep BUNDLE_IDENTIFIER = com.buzz.buzzMobile"
|
||||
|| fail "Release.xcconfig must keep BUNDLE_IDENTIFIER = xyz.block.buzz.mobile"
|
||||
grep -q '^APP_DISPLAY_NAME = Buzz$' "$release_xcconfig" \
|
||||
&& pass "Release.xcconfig keeps the production display name" \
|
||||
|| fail "Release.xcconfig must keep APP_DISPLAY_NAME = Buzz"
|
||||
# Split the retired identifiers so the regression test does not match itself.
|
||||
retired_bundle_id='com.buzz.buzz'"Mobile"
|
||||
if git -C "$repo_root" grep -q -F "$retired_bundle_id"; then
|
||||
fail "tracked files must not retain the retired iOS bundle identifier"
|
||||
else
|
||||
pass "tracked files do not retain the retired iOS bundle identifier"
|
||||
fi
|
||||
grep -q '<key>com.apple.developer.devicecheck.appattest-environment</key>' "$runner_entitlements" \
|
||||
&& pass "Runner uses the App Attest entitlement key accepted by Apple" \
|
||||
|| fail "Runner must use com.apple.developer.devicecheck.appattest-environment"
|
||||
retired_entitlement_key='com.apple.developer.app-attest.'"environment"
|
||||
if grep -q "$retired_entitlement_key" "$runner_entitlements"; then
|
||||
fail "Runner must not retain the invalid App Attest entitlement key"
|
||||
else
|
||||
pass "Runner omits the invalid App Attest entitlement key"
|
||||
fi
|
||||
team_map=$(awk '
|
||||
/\/\* (Debug|Release|Profile) \*\/ = \{/ {
|
||||
config = $3
|
||||
}
|
||||
/DEVELOPMENT_TEAM =/ {
|
||||
team = $3
|
||||
gsub(/;/, "", team)
|
||||
print config, team
|
||||
}
|
||||
' "$pbxproj" | sort)
|
||||
expected_team_map=$(printf '%s\n' \
|
||||
'Debug JMTDPW9CG3' \
|
||||
'Debug JMTDPW9CG3' \
|
||||
'Profile EYF346PHUG' \
|
||||
'Profile EYF346PHUG' \
|
||||
'Release EYF346PHUG' \
|
||||
'Release EYF346PHUG')
|
||||
if [[ "$team_map" == "$expected_team_map" ]]; then
|
||||
pass "Runner and NotificationService use dogfood for Debug and production for Release/Profile"
|
||||
else
|
||||
fail "unexpected iOS development-team map: $team_map"
|
||||
fi
|
||||
grep -q '<string>$(APP_DISPLAY_NAME)</string>' "$plist" \
|
||||
&& pass "Info.plist display name resolves from build settings" \
|
||||
|| fail "Info.plist CFBundleDisplayName must be \$(APP_DISPLAY_NAME)"
|
||||
|
||||
Reference in New Issue
Block a user