diff --git a/src/pages/Blocked.tsx b/src/pages/Blocked.tsx index ba4a33b..84cc165 100644 --- a/src/pages/Blocked.tsx +++ b/src/pages/Blocked.tsx @@ -20,7 +20,7 @@ import { DialogContent, DialogContentText, DialogActions, - TextField, + TextField } from "@material-ui/core"; import { withSnackbar } from "notistack"; @@ -53,7 +53,7 @@ class Blocked extends Component { viewIsLoading: true, viewDidLoad: false, viewDidError: false, - blockTextField: "", + blockTextField: "" }; } @@ -64,14 +64,14 @@ class Blocked extends Component { this.setState({ blockedServers: resp.data, viewDidLoad: true, - viewIsLoading: false, + viewIsLoading: false }); }) .catch((err: Error) => { console.error(err); this.setState({ viewIsLoading: false, - viewDidError: true, + viewDidError: true }); }); } @@ -90,7 +90,7 @@ class Blocked extends Component { this.setState({ blockTextField: "", addBlockOpen: false, - blockedServers, + blockedServers }); }); } @@ -105,7 +105,7 @@ class Blocked extends Component { blockedServers.splice(blockedServers.indexOf(domain), 1); } this.setState({ - blockedServers, + blockedServers }); }) .catch((err: Error) => { @@ -118,7 +118,7 @@ class Blocked extends Component { updateTextField(value: string) { this.setState({ - blockTextField: value, + blockTextField: value }); } @@ -140,7 +140,7 @@ class Blocked extends Component { fullWidth value={this.state.blockTextField} placeholder="mastodon.online" - onChange={(e) => this.updateTextField(e.target.value)} + onChange={e => this.updateTextField(e.target.value)} > @@ -153,9 +153,7 @@ class Blocked extends Component { diff --git a/src/pages/Welcome.tsx b/src/pages/Welcome.tsx index 1c2300d..503d38d 100644 --- a/src/pages/Welcome.tsx +++ b/src/pages/Welcome.tsx @@ -19,7 +19,7 @@ import { ListItemAvatar, ListItemSecondaryAction, IconButton, - InputAdornment, + InputAdornment } from "@material-ui/core"; import { styles } from "./WelcomePage.styles"; import Mastodon from "megalodon"; @@ -28,7 +28,7 @@ import { createHyperspaceApp, getRedirectAddress, inDisallowedDomains, - instancesBearerKey, + instancesBearerKey } from "../utilities/login"; import { parseUrl } from "query-string"; import { getConfig } from "../utilities/settings"; @@ -39,7 +39,7 @@ import { Config } from "../types/Config"; import { getAccountRegistry, loginWithAccount, - removeAccountFromRegistry, + removeAccountFromRegistry } from "../utilities/accounts"; import { MultiAccount } from "../types/Account"; @@ -210,7 +210,7 @@ class WelcomePage extends Component { authCode: "", emergencyMode: false, version: "", - willAddAccount: false, + willAddAccount: false }; // Read the configuration data and update the state @@ -253,7 +253,7 @@ class WelcomePage extends Component { ? config.location : `https://${window.location.host}`, redirectAddressIsDynamic: config.location === "dynamic", - version: config.version, + version: config.version }); } }) @@ -274,7 +274,7 @@ class WelcomePage extends Component { if (localStorage.getItem("login")) { this.getSavedSession(); this.setState({ - foundSavedLogin: true, + foundSavedLogin: true }); this.checkForToken(); } @@ -334,7 +334,7 @@ class WelcomePage extends Component { clientId: session.clientId, clientSecret: session.clientSecret, authUrl: session.authUrl, - emergencyMode: session.emergency, + emergencyMode: session.emergency }); } @@ -392,8 +392,8 @@ class WelcomePage extends Component { this.setState({ user: newUser }); return "https://" + newUser.split("@")[1]; } else { - let newUser = `${user}@${this.state.registerBase ?? "mastodon.online" - }`; + let newUser = `${user}@${this.state.registerBase ?? + "mastodon.online"}`; this.setState({ user: newUser }); return ( "https://" + (this.state.registerBase ?? "mastodon.online") @@ -403,8 +403,8 @@ class WelcomePage extends Component { // Otherwise, treat them as if they're from the server else { - let newUser = `${user}@${this.state.registerBase ?? "mastodon.online" - }`; + let newUser = `${user}@${this.state.registerBase ?? + "mastodon.online"}`; this.setState({ user: newUser }); return "https://" + (this.state.registerBase ?? "mastodon.online"); } @@ -413,10 +413,11 @@ class WelcomePage extends Component { /** * Check the user string for any errors and then create a client with an * ID and secret to start the authorization process. + * @param bypassChecks Whether to bypass the checks in place. */ - startLogin() { + startLogin(bypassChecks: boolean = false) { // Check if we have errored - let error = this.checkForErrors(this.state.user); + let error = this.checkForErrors(this.state.user, bypassChecks); // If we didn't, create the Hyperspace app to register onto that Mastodon // server. @@ -439,7 +440,7 @@ class WelcomePage extends Component { clientId: resp.clientId, clientSecret: resp.clientSecret, authUrl: resp.url, - emergency: false, + emergency: false }; localStorage.setItem( "login", @@ -451,8 +452,17 @@ class WelcomePage extends Component { clientId: resp.clientId, clientSecret: resp.clientSecret, authUrl: resp.url, - proceedToGetCode: true, + proceedToGetCode: true }); + }) + .catch((err: Error) => { + this.props.enqueueSnackbar( + `Failed to register app at ${baseurl.replace( + "https://", + "" + )}` + ); + console.error(err); }); } } @@ -475,7 +485,7 @@ class WelcomePage extends Component { Mastodon.registerApp( this.state.brandName ?? "Hyperspace", { - scopes: scopes, + scopes: scopes }, baseurl ) @@ -485,7 +495,7 @@ class WelcomePage extends Component { clientId: appData.clientId, clientSecret: appData.clientSecret, authUrl: appData.url, - emergency: true, + emergency: true }; localStorage.setItem( "login", @@ -496,7 +506,7 @@ class WelcomePage extends Component { this.setState({ clientId: appData.clientId, clientSecret: appData.clientSecret, - authUrl: appData.url, + authUrl: appData.url }); }); } @@ -528,15 +538,21 @@ class WelcomePage extends Component { clientSecret: session.clientSecret, authUrl: session.authUrl, emergencyMode: session.emergency, - proceedToGetCode: true, + proceedToGetCode: true }); } } /** * Check the user input string for any possible errors + * @param username The username to read and check for errors + * @param bypassesInstanceNameCheck Whether to bypass the instance name validation process. Defaults to false. + * @return Whether an error has occured in the validation. */ - checkForErrors(username: string): boolean { + checkForErrors( + username: string, + bypassesInstanceNameCheck: boolean = false + ): boolean { let userInputError = false; let userInputErrorMessage = ""; @@ -555,28 +571,31 @@ class WelcomePage extends Component { if (inDisallowedDomains(baseUrl)) { this.setState({ userInputError: true, - userInputErrorMessage: `Signing in with an account from ${baseUrl} isn't supported.`, + userInputErrorMessage: `Signing in with an account from ${baseUrl} isn't supported.` }); return true; } else { + if (bypassesInstanceNameCheck) { + return false; + } // Are we unable to ping the server? axios .get( "https://instances.social/api/1.0/instances/show?name=" + - baseUrl, + baseUrl, { headers: { - Authorization: `Bearer ${instancesBearerKey}`, - }, + Authorization: `Bearer ${instancesBearerKey}` + } } ) .catch((err: Error) => { let userInputError = true; let userInputErrorMessage = - "Instance name is invalid."; + "We couldn't recognize this instance."; this.setState({ userInputError, - userInputErrorMessage, + userInputErrorMessage }); return true; }); @@ -633,9 +652,9 @@ class WelcomePage extends Component { let redirectUrl: string | undefined = this.state.emergencyMode || - clientLoginSession.authUrl.includes( - "urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob" - ) + clientLoginSession.authUrl.includes( + "urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob" + ) ? undefined : getRedirectAddress(conf.location); @@ -658,8 +677,8 @@ class WelcomePage extends Component { }) .catch((err: Error) => { this.props.enqueueSnackbar( - `Couldn't authorize ${this.state.brandName ?? "Hyperspace" - }: ${err.name}`, + `Couldn't authorize ${this.state.brandName ?? + "Hyperspace"}: ${err.name}`, { variant: "error" } ); console.error(err.message); @@ -677,8 +696,8 @@ class WelcomePage extends Component { window.location.protocol === "hyperspace:" ? "hyperspace://hyperspace/app/" : this.state.redirectAddressIsDynamic - ? `https://${window.location.host}/#/` - : this.state.defaultRedirectAddress + "/#/"; + ? `https://${window.location.host}/#/` + : this.state.defaultRedirectAddress + "/#/"; } /** @@ -770,20 +789,30 @@ class WelcomePage extends Component { label="Username" fullWidth placeholder="example@mastodon.example" - onChange={(event) => - this.updateUserInfo(event.target.value) - } - onKeyDown={(event) => this.watchUsernameField(event)} + onChange={event => this.updateUserInfo(event.target.value)} + onKeyDown={event => this.watchUsernameField(event)} error={this.state.userInputError} InputProps={{ startAdornment: ( @ - ), + ) }} /> {this.state.userInputError ? ( {this.state.userInputErrorMessage} + {this.state.userInputErrorMessage === + "We couldn't recognize this instance." ? ( + +
+ this.startLogin(true)} + > + Try anyway + +
+ ) : null}
) : null}
@@ -919,10 +948,10 @@ class WelcomePage extends Component { variant="outlined" label="Authorization code" fullWidth - onChange={(event) => + onChange={event => this.updateAuthCode(event.target.value) } - onKeyDown={(event) => this.watchAuthField(event)} + onKeyDown={event => this.watchAuthField(event)} /> @@ -974,8 +1003,8 @@ class WelcomePage extends Component {
@@ -989,17 +1018,17 @@ class WelcomePage extends Component { {this.state.authorizing ? this.showAuthorizationLoader() : this.state.proceedToGetCode - ? this.showLoginAuth() - : getAccountRegistry().length > 0 && - !this.state.willAddAccount - ? this.showMultiAccount() - : this.showLanding()} + ? this.showLoginAuth() + : getAccountRegistry().length > 0 && + !this.state.willAddAccount + ? this.showMultiAccount() + : this.showLanding()}
© {new Date().getFullYear()}{" "} {this.state.brandName && - this.state.brandName !== "Hyperspace" + this.state.brandName !== "Hyperspace" ? `${this.state.brandName} developers and the ` : ""}{" "} { > License {" "} - | + |{" "} { {this.state.brandName ?? "Hypersapce"} v. {this.state.version}{" "} {this.state.brandName && - this.state.brandName !== "Hyperspace" + this.state.brandName !== "Hyperspace" ? "(Hyperspace-like)" : null}