Files
buzz/mobile/scripts/validate_push_gateway_origin.dart
Tom Brow 76f7e5ef0c feat(push): make gateway origin configurable (#7261)
Make the push gateway origin configurable across the relay, gateway,
mobile client, and deployment chart.

This is a fresh deployment. The gateway has only run on personal
development infrastructure, and push has no existing enabled users.
Legacy migration, configured-to-unconfigured mobile transitions, and
rolling upgrades from pre-launch gateway binaries are not supported.

Populated pre-launch databases are rejected with an informative error
before migrations run; their data is untouched. Mobile builds may omit
the gateway URL, leaving push unavailable. Once push is enabled,
subsequent builds must retain that configuration.

### Validation

- All applicable CI checks pass at
`5f546cfaf403f0386f146d213adfb4392f4ec29c`, including Rust,
mobile/Swift, desktop/integration, security, image builds, and Helm
checks. An unrelated agent cancellation test passed on retry.
- PostgreSQL CI passed 384 tests, including the production-entry-point
regression for refusing populated pre-launch databases before
migrations, fresh initialization, and subsequent initialized
deployments.
- Focused local validation passed all 10 gateway PostgreSQL tests under
the CI discovery filter and all 3 unconfigured-mobile tests.
Repository-wide PostgreSQL discovery validation and the complete
pre-push hooks passed.
- Physical-device APNs/App Attest behavior and deployment to a live
cluster were not verified in this work.

---------

Signed-off-by: Tom Brow <tomb@block.xyz>
Co-authored-by: Codex <noreply@openai.com>
2026-09-15 14:56:45 -07:00

38 lines
1.2 KiB
Dart

import 'dart:io';
bool isValidPushGatewayOrigin(String value, {bool requireHttps = false}) {
try {
final uri = Uri.parse(value);
if (requireHttps
? uri.scheme != 'https'
: uri.scheme != 'http' && uri.scheme != 'https') {
return false;
}
if (!uri.hasAuthority || uri.host.isEmpty || uri.userInfo.isNotEmpty) {
return false;
}
if (uri.path.isNotEmpty && uri.path != '/') return false;
if (uri.hasQuery || uri.hasFragment) return false;
if (requireHttps && uri.hasPort) return false;
final port = uri.port;
return port >= 1 && port <= 65535;
} on FormatException {
return false;
}
}
void main(List<String> arguments) {
final requireHttps =
arguments.isNotEmpty && arguments.first == '--require-https';
final values = requireHttps ? arguments.skip(1).toList() : arguments;
if (values.length == 1 &&
isValidPushGatewayOrigin(values.single, requireHttps: requireHttps)) {
return;
}
final requirement = requireHttps
? 'an HTTPS origin without an explicit port, credentials, path, query, or fragment'
: 'an HTTP(S) origin without credentials, path, query, or fragment';
stderr.writeln('error: BUZZ_PUSH_GATEWAY_URL must be $requirement.');
exitCode = 1;
}