Skip to content

Commit e83938b

Browse files
chrisbobbegnprice
authored andcommitted
api: Parse realm_uri into a URL object in api.getServerSettings
This fixes at least a latent bug: now, if realm_uri doesn't parse, we'll give a "can't connect to server" error to the user, instead of crashing out to RootErrorBoundary.
1 parent 6d14c12 commit e83938b

File tree

2 files changed

+25
-19
lines changed

2 files changed

+25
-19
lines changed

src/api/settings/getServerSettings.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ type ApiResponseServerSettings = {|
7171

7272
export type ServerSettings = $ReadOnly<{|
7373
...ApiResponseServerSettings,
74+
+realm_uri: URL,
7475
+realm_name: string,
7576
|}>;
7677

@@ -95,6 +96,7 @@ function transform(raw: ApiResponseServerSettings): ServerSettings {
9596

9697
return {
9798
...raw,
99+
realm_uri: new URL(raw.realm_uri),
98100
realm_name,
99101
};
100102
}

src/start/AuthScreen.js

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,7 @@ type OuterProps = $ReadOnly<{|
176176
route: RouteProp<'auth', {| serverSettings: ServerSettings |}>,
177177
|}>;
178178

179-
type SelectorProps = $ReadOnly<{|
180-
// Don't let this change across the component's lifecycle. It must be
181-
// clear and predictable which realm the user is entrusting their
182-
// credentials to. (And other sensitive info, e.g., from the Apple auth
183-
// native flow.)
184-
realm: URL,
185-
|}>;
179+
type SelectorProps = $ReadOnly<{||}>;
186180

187181
type Props = $ReadOnly<{|
188182
...OuterProps,
@@ -237,26 +231,32 @@ class AuthScreenInner extends PureComponent<Props> {
237231
*/
238232
beginWebAuth = async (url: string) => {
239233
otp = await webAuth.generateOtp();
240-
webAuth.openBrowser(new URL(url, this.props.realm).toString(), otp);
234+
webAuth.openBrowser(
235+
new URL(url, this.props.route.params.serverSettings.realm_uri).toString(),
236+
otp,
237+
);
241238
};
242239

243240
endWebAuth = (event: LinkingEvent) => {
244241
webAuth.closeBrowser();
245242

246-
const { dispatch, realm } = this.props;
243+
const { dispatch } = this.props;
244+
const realm = this.props.route.params.serverSettings.realm_uri;
247245
const auth = webAuth.authFromCallbackUrl(event.url, otp, realm);
248246
if (auth) {
249247
dispatch(loginSuccess(auth.realm, auth.email, auth.apiKey));
250248
}
251249
};
252250

253251
handleDevAuth = () => {
254-
this.props.navigation.push('dev-auth', { realm: this.props.realm });
252+
this.props.navigation.push('dev-auth', {
253+
realm: this.props.route.params.serverSettings.realm_uri,
254+
});
255255
};
256256

257257
handlePassword = () => {
258258
const { serverSettings } = this.props.route.params;
259-
const { realm } = this.props;
259+
const realm = serverSettings.realm_uri;
260260
this.props.navigation.push('password-auth', {
261261
realm,
262262
requireEmailFormat: serverSettings.require_email_format_usernames,
@@ -284,7 +284,12 @@ class AuthScreenInner extends PureComponent<Props> {
284284
id_token: credential.identityToken,
285285
});
286286

287-
openLinkEmbedded(new URL(`/complete/apple/?${params}`, this.props.realm).toString());
287+
openLinkEmbedded(
288+
new URL(
289+
`/complete/apple/?${params}`,
290+
this.props.route.params.serverSettings.realm_uri,
291+
).toString(),
292+
);
288293

289294
// Currently, the rest is handled with the `zulip://` redirect,
290295
// same as in the web flow.
@@ -306,7 +311,7 @@ class AuthScreenInner extends PureComponent<Props> {
306311
//
307312
// (For other realms, we'll simply fall back to the web flow, which
308313
// handles things appropriately without relying on that assumption.)
309-
return isAppOwnDomain(this.props.realm);
314+
return isAppOwnDomain(this.props.route.params.serverSettings.realm_uri);
310315
};
311316

312317
handleAuth = async (method: AuthenticationMethodDetails) => {
@@ -331,7 +336,10 @@ class AuthScreenInner extends PureComponent<Props> {
331336
<Centerer>
332337
<RealmInfo
333338
name={serverSettings.realm_name}
334-
iconUrl={new URL(serverSettings.realm_icon, this.props.realm).toString()}
339+
iconUrl={new URL(
340+
serverSettings.realm_icon,
341+
this.props.route.params.serverSettings.realm_uri,
342+
).toString()}
335343
/>
336344
{activeAuthentications(
337345
serverSettings.authentication_methods,
@@ -363,10 +371,6 @@ class AuthScreenInner extends PureComponent<Props> {
363371
}
364372
}
365373

366-
const AuthScreen: ComponentType<OuterProps> = connect((state, props) => ({
367-
// Not from the Redux state, but it's convenient to validate the URL
368-
// in one central place, like here.
369-
realm: new URL(props.route.params.serverSettings.realm_uri),
370-
}))(AuthScreenInner);
374+
const AuthScreen: ComponentType<OuterProps> = connect<{||}, _, _>()(AuthScreenInner);
371375

372376
export default AuthScreen;

0 commit comments

Comments
 (0)