diff --git a/openpilot/starpilot/galaxy/server.py b/openpilot/starpilot/galaxy/server.py index 67b1bbd685..6c4921a05b 100644 --- a/openpilot/starpilot/galaxy/server.py +++ b/openpilot/starpilot/galaxy/server.py @@ -781,7 +781,7 @@ def make_server(*, port=8082, host='127.0.0.1', monitor=None, owner=None, crashe token = quote(f"{record['slug']}:{record['session']}", safe='') if path.endswith('/qr.svg'): from openpilot.common.qrcode import _Qr, _capacity - raw = ('starpilot-remote://add?key=' + quote(token, safe='')).encode() + raw = ('starpilot-remote://add?key=' + token).encode() version = next(version for version in range(1, 21) if 4 + 8 + len(raw) * 8 <= _capacity(version) * 8) matrix = _Qr(version, raw).modules size = len(matrix) + 8 diff --git a/openpilot/starpilot/galaxy/tests/test_sentry_notifications_http.py b/openpilot/starpilot/galaxy/tests/test_sentry_notifications_http.py index 05a20bafbb..58fd50ae73 100644 --- a/openpilot/starpilot/galaxy/tests/test_sentry_notifications_http.py +++ b/openpilot/starpilot/galaxy/tests/test_sentry_notifications_http.py @@ -33,7 +33,7 @@ class NotificationHTTPTests(unittest.TestCase): return result try: cookie = request()[2]['Set-Cookie'].split(';', 1)[0] - code, result, _ = request({'action': 'appSubscribe', 'token': 'test-token', 'appId': 'link.firestar.galaxy', 'label': 'Phone'}, cookie) + code, result, _ = request({'action': 'appSubscribe', 'token': 'test-token', 'appId': 'com.starpilot.galaxy', 'label': 'Phone'}, cookie) self.assertEqual(code, 200) self.assertNotIn('test-token', json.dumps(result)) self.assertEqual(request({'action': 'test', 'target': 'app', 'id': 'missing'}, cookie)[0], 404) diff --git a/openpilot/starpilot/galaxy/web/js/companion.js b/openpilot/starpilot/galaxy/web/js/companion.js index 9cb1e1b417..1b33ded54c 100644 --- a/openpilot/starpilot/galaxy/web/js/companion.js +++ b/openpilot/starpilot/galaxy/web/js/companion.js @@ -1,6 +1,7 @@ import { requestJson } from './startup.js' import { GxNotice } from './notice.js' import { BluetoothNotice, bluetoothConnection } from './bluetooth-notice.js' +import { ANDROID_BETA_URL } from './install-app.js' export function newerCompanionVersion(available, installed) { const parts = version => typeof version === 'string' && /^\d+(?:\.\d+){1,3}$/.test(version) ? version.split('.').map(Number) : [] @@ -23,7 +24,7 @@ export const GalaxyCompanion = { components: { GxNotice, BluetoothNotice }, emits: ['status'], props: { mode: String, unauthorized: Function }, - data: () => ({ status: null, error: '', native: !!window.StarPilotApp?.uplinkState, sharing: false, autoStart: false, + data: () => ({ status: null, error: '', betaUrl: ANDROID_BETA_URL, native: !!window.StarPilotApp?.uplinkState, sharing: false, autoStart: false, bluetooth: bluetoothConnection(), nativeBytes: 0, busy: false, generation: 0, alive: false }), computed: { windowAutoStart() { return !!window.StarPilotApp?.setAutoStart } }, mounted() { this.start() }, @@ -87,7 +88,7 @@ export const GalaxyCompanion = {

Phone internet requires the Galaxy hotspot. Settings and small requests remain available. {{ error }} diff --git a/openpilot/starpilot/galaxy/web/js/galaxy.js b/openpilot/starpilot/galaxy/web/js/galaxy.js index b0313d178e..7f96390c37 100644 --- a/openpilot/starpilot/galaxy/web/js/galaxy.js +++ b/openpilot/starpilot/galaxy/web/js/galaxy.js @@ -1,7 +1,7 @@ import { GxState } from "./state.js" import { GxNotice } from "./notice.js" import { requestJson } from "./startup.js" -import { InstallApp, isIosDevice } from "./install-app.js" +import { ANDROID_BETA_URL, InstallApp, isIosDevice } from "./install-app.js" import { GalaxyCompanion, newerCompanionVersion } from "./companion.js" import { GalaxyHotspot } from "./hotspot.js" import { LocalAccess } from "./local-access.js" @@ -15,7 +15,7 @@ export const GalaxyPage = { components: { GxState, GxNotice, BluetoothNotice, InstallApp, GalaxyHotspot, GalaxyCompanion, LocalAccess }, props: { mode: { type: String, required: true }, unauthorized: { type: Function, required: true } }, data: () => ({ loading: true, paired: false, url: "", tunnelClientAvailable: false, legacyPassword: false, - appKey: '', keyVisible: false, legacyPairingAvailable: false, password: "", busy: false, error: "", companionStatus: null, + appKey: '', keyVisible: false, betaUrl: ANDROID_BETA_URL, legacyPairingAvailable: false, password: "", busy: false, error: "", companionStatus: null, bluetooth: bluetoothConnection(), nativeVersion: window.StarPilotApp?.version?.() || '', dismissedUpdateVersion: dismissedUpdate(), ios: isIosDevice() }), computed: { @@ -33,7 +33,8 @@ export const GalaxyPage = { mounted() { this.load() }, methods: { async showAppKey() { - try { const data = await this.request('./api/galaxy/session'); this.appKey = data.paired ? decodeURIComponent(data.sessionToken) : ''; this.keyVisible = !!this.appKey } + const url = this.url + try { const data = await this.request('./api/galaxy/session'); if (this.url !== url || !this.paired) return; this.appKey = data.paired ? decodeURIComponent(data.sessionToken) : ''; this.keyVisible = !!this.appKey } catch (error) { this.error = error.message } }, async copyAppKey() { @@ -73,6 +74,8 @@ export const GalaxyPage = { const data = await this.request("./api/galaxy/pair", { password: this.password }) this.paired = data.paired this.url = data.url + this.appKey = '' + this.keyVisible = false this.password = "" } catch (error) { this.error = error.message } finally { this.busy = false } @@ -85,6 +88,8 @@ export const GalaxyPage = { await this.request("./api/galaxy/unpair", {}) this.paired = false this.url = "" + this.appKey = '' + this.keyVisible = false } catch (error) { this.error = error.message } finally { this.busy = false } }, @@ -100,7 +105,7 @@ export const GalaxyPage = { Version {{ availableAppVersion }} is available. Installed: {{ installedAppVersion }}. Connect to your comma to set up remote access. diff --git a/openpilot/starpilot/galaxy/web/js/sentry-notifications.js b/openpilot/starpilot/galaxy/web/js/sentry-notifications.js index e36bb22c78..55267e9b73 100644 --- a/openpilot/starpilot/galaxy/web/js/sentry-notifications.js +++ b/openpilot/starpilot/galaxy/web/js/sentry-notifications.js @@ -61,7 +61,7 @@ export const SentryNotifications = { components: { GxNotice }, name: "SentryNotifications", props: { mode: { type: String, required: true }, unauthorized: { type: Function, required: true } }, - data: () => ({ nativePush: !!window.StarPilotApp?.sentryPush, pushState: {}, testPoll: null, channels, labels, notifications: null, notificationBusy: false, notificationError: "", + data: () => ({ nativePush: !!window.StarPilotApp?.sentryPush, pushState: {}, testPoll: null, relayUrl: '', channels, labels, notifications: null, notificationBusy: false, notificationError: "", drafts: Object.fromEntries(channels.map(name => [name, { url: "", token: "" }])) }), created() { this.client = new NotificationClient({ publish: update => Object.assign(this.$data, update), unauthorized: this.unauthorized }) }, mounted() { @@ -83,6 +83,9 @@ export const SentryNotifications = { removePhone(id) { return this.client.run({ action: 'appUnsubscribe', id }) }, simulate() { return this.client.run({ action: 'simulate' }) }, canSimulate() { return !!window.StarPilotApp || location.protocol === 'http:' }, + async saveRelay() { + if (await this.client.run({ action: 'configure', channel: 'appPush', enabled: true, url: this.relayUrl, token: '' })) this.relayUrl = '' + }, start() { clearInterval(this.poll) this.refreshPush() @@ -132,13 +135,15 @@ export const SentryNotifications = { The notification queue is full. Some events could not be queued.