Improve interaction modal error handling (#26795)

lolsob-rspec
Claire 2023-09-05 23:49:48 +02:00 committed by GitHub
parent 529ee44ff6
commit a8a25dcbdb
3 changed files with 51 additions and 7 deletions

View File

@ -41,5 +41,7 @@ class Api::V1::Peers::SearchController < Api::BaseController
domain = TagManager.instance.normalize_domain(domain)
@domains = Instance.searchable.where(Instance.arel_table[:domain].matches("#{Instance.sanitize_sql_like(domain)}%", false, true)).limit(10).pluck(:domain)
end
rescue Addressable::URI::InvalidURIError
@domains = []
end
end

View File

@ -100,8 +100,41 @@ class LoginForm extends React.PureComponent {
this.input = c;
};
isValueValid = (value) => {
let likelyAcct = false;
let url = null;
if (value.startsWith('/')) {
return false;
}
if (value.startsWith('@')) {
value = value.slice(1);
likelyAcct = true;
}
// The user is in the middle of typing something, do not error out
if (value === '') {
return true;
}
if (/^https?:\/\//.test(value) && !likelyAcct) {
url = value;
} else {
url = `https://${value}`;
}
try {
new URL(url);
return true;
} catch(_) {
return false;
}
};
handleChange = ({ target }) => {
this.setState(state => ({ value: target.value, isLoading: true, error: false, options: addInputToOptions(target.value, state.networkOptions) }), () => this._loadOptions());
const error = !this.isValueValid(target.value);
this.setState(state => ({ error, value: target.value, isLoading: true, options: addInputToOptions(target.value, state.networkOptions) }), () => this._loadOptions());
};
handleMessage = (event) => {
@ -115,11 +148,18 @@ class LoginForm extends React.PureComponent {
this.setState({ isSubmitting: false, error: true });
} else if (event.data?.type === 'fetchInteractionURL-success') {
if (/^https?:\/\//.test(event.data.template)) {
if (localStorage) {
localStorage.setItem(PERSISTENCE_KEY, event.data.uri_or_domain);
}
try {
const url = new URL(event.data.template.replace('{uri}', encodeURIComponent(resourceUrl)));
window.location.href = event.data.template.replace('{uri}', encodeURIComponent(resourceUrl));
if (localStorage) {
localStorage.setItem(PERSISTENCE_KEY, event.data.uri_or_domain);
}
window.location.href = url;
} catch (e) {
console.error(e);
this.setState({ isSubmitting: false, error: true });
}
} else {
this.setState({ isSubmitting: false, error: true });
}
@ -259,7 +299,7 @@ class LoginForm extends React.PureComponent {
spellcheck='false'
/>
<Button onClick={this.handleSubmit} disabled={isSubmitting}><FormattedMessage id='interaction_modal.login.action' defaultMessage='Take me home' /></Button>
<Button onClick={this.handleSubmit} disabled={isSubmitting || error}><FormattedMessage id='interaction_modal.login.action' defaultMessage='Take me home' /></Button>
</div>
{hasPopOut && (

View File

@ -140,7 +140,9 @@ const fromAcct = (acct: string) => {
};
const fetchInteractionURL = (uri_or_domain: string) => {
if (/^https?:\/\//.test(uri_or_domain)) {
if (uri_or_domain === '') {
fetchInteractionURLFailure();
} else if (/^https?:\/\//.test(uri_or_domain)) {
fromURL(uri_or_domain);
} else if (uri_or_domain.includes('@')) {
fromAcct(uri_or_domain);