Skip to content
This repository has been archived by the owner on Jan 6, 2024. It is now read-only.

Commit

Permalink
Overseer urlencode fix
Browse files Browse the repository at this point in the history
  • Loading branch information
darkalfx committed Mar 13, 2021
1 parent 78776a8 commit 27a84e2
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Requestrr.WebApi/ClientApp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Requestrr.WebApi/ClientApp/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Requestrr",
"version": "1.0.15",
"version": "1.0.16",
"description": "Requestrr is a server designed to faciliate the request of media through chat applications.",
"main": "index.js",
"author": "Darkalfx",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Overseerr extends React.Component {
apiKey: "",
isApiKeyValid: false,
defaultApiUserID: "",
isDefaultApiUserIDValid: true,
useSSL: "",
apiVersion: "",
};
Expand All @@ -41,6 +42,7 @@ class Overseerr extends React.Component {
this.updateStateFromProps = this.updateStateFromProps.bind(this);
this.validateNonEmptyString = this.validateNonEmptyString.bind(this);
this.validatePort = this.validatePort.bind(this);
this.validateDefaultUserId = this.validateDefaultUserId.bind(this);
}

componentDidMount() {
Expand All @@ -61,6 +63,7 @@ class Overseerr extends React.Component {
apiKey: props.settings.apiKey,
isApiKeyValid: false,
defaultApiUserID: props.settings.defaultApiUserID,
isDefaultApiUserIDValid: true,
useSSL: props.settings.useSSL,
apiVersion: props.settings.version,
});
Expand All @@ -80,12 +83,17 @@ class Overseerr extends React.Component {
return /^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/.test(value);
}

validateDefaultUserId = value => {
return (!value || value.length === 0 || /^\s*$/.test(value)) || (/^[1-9]\d*$/).test(value);
}

onTestSettings = e => {
e.preventDefault();

if (!this.state.isTestingSettings
&& this.state.isHostnameValid
&& this.state.isPortValid
&& this.state.isDefaultApiUserIDValid
&& this.state.isApiKeyValid) {
this.setState({ isTestingSettings: true });

Expand All @@ -94,6 +102,7 @@ class Overseerr extends React.Component {
port: this.state.port,
apiKey: this.state.apiKey,
useSSL: this.state.useSSL,
defaultApiUserID: this.state.defaultApiUserID,
version: this.state.apiVersion,
})
.then(data => {
Expand Down Expand Up @@ -140,7 +149,7 @@ class Overseerr extends React.Component {
}

onValidate() {
this.props.onValidate(this.state.isApiKeyValid && this.state.isHostnameValid && this.state.isPortValid);
this.props.onValidate(this.state.isApiKeyValid && this.state.isHostnameValid && this.state.isPortValid && this.state.isDefaultApiUserIDValid);
}

render() {
Expand Down Expand Up @@ -200,12 +209,17 @@ class Overseerr extends React.Component {
</Col>
</Row>
<Row>
<Col lg="6">
<Textbox
<Col lg="6">
<ValidatedTextbox
name="Default Overseerr User ID for requests"
placeholder="Enter default user ID (Optional)"
alertClassName="mt-3 mb-0"
errorMessage="The user id must be a number."
isSubmitted={this.props.isSubmitted}
value={this.state.defaultApiUserID}
onChange={newDefaultApiUserID => this.setState({ defaultApiUserID: newDefaultApiUserID }, this.onValueChange)} />
validation={this.validateDefaultUserId}
onChange={newDefaultApiUserID => this.setState({ defaultApiUserID: newDefaultApiUserID }, this.onValueChange)}
onValidate={isValid => this.setState({ isDefaultApiUserIDValid: isValid }, this.onValidate)} />
</Col>
<Col lg="6"></Col>
</Row>
Expand Down Expand Up @@ -250,7 +264,7 @@ class Overseerr extends React.Component {
<Row>
<Col>
<FormGroup className="text-right">
<button onClick={this.onTestSettings} disabled={!this.state.isHostnameValid || !this.state.isPortValid || !this.state.isApiKeyValid} className="btn btn-icon btn-3 btn-default" type="button">
<button onClick={this.onTestSettings} disabled={!this.state.isHostnameValid || !this.state.isPortValid || !this.state.isApiKeyValid || !this.state.isDefaultApiUserIDValid} className="btn btn-icon btn-3 btn-default" type="button">
<span className="btn-inner--icon">
{
this.state.isTestingSettings ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Footer extends React.Component {
<Col xl="6">
<div className="copyright text-center text-xl-left text-muted">
© {new Date().getFullYear()}{" "}
Requestrr (v1.0.15)
Requestrr (v1.0.16)
</div>
</Col>
</Row>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class AuthFooter extends React.Component {
<Col xl="6">
<div className="copyright text-center text-xl-left text-muted">
© {new Date().getFullYear()}{" "}
Requestrr (v1.0.15)
Requestrr (v1.0.16)
</div>
</Col>
</Row>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export function testOverseerrSettings(settings) {
"Hostname": settings.hostname,
"Port": Number(settings.port),
"ApiKey": settings.apiKey,
'DefaultApiUserID': settings.defaultApiUserID,
"UseSSL": settings.useSSL,
"Version": settings.version,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export function testOverseerrSettings(settings) {
"Hostname": settings.hostname,
"Port": Number(settings.port),
"ApiKey": settings.apiKey,
'DefaultApiUserID': settings.defaultApiUserID,
"UseSSL": settings.useSSL,
"Version": settings.version,
})
Expand Down
2 changes: 1 addition & 1 deletion Requestrr.WebApi/ClientApp/src/views/ChatClients.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ class ChatClients extends React.Component {
name="Channel(s) to monitor"
create={true}
searchable={true}
placeholder="Enter channels here. Leave blank for all channels."
placeholder="Enter channels names here. Leave blank for all channels."
labelField="name"
valueField="id"
dropdownHandle={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public async Task<IActionResult> TestOverseerrSettings([FromBody]TestOverseerrSe
Hostname = model.Hostname.Trim(),
Port = model.Port,
UseSSL = model.UseSSL,
DefaultApiUserID = model.DefaultApiUserID,
Version = model.Version,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@
{
public class OverseerrSettingsModel : TestOverseerrSettingsModel
{
public string DefaultApiUserID { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class TestOverseerrSettingsModel
public string ApiKey { get; set; }
[Required]
public bool UseSSL { get; set; }
public string DefaultApiUserID { get; set; }
[Required]
public string Version { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@ public static async Task TestConnectionAsync(HttpClient httpClient, ILogger<Over
throw new Exception("Invalid host and/or port");
}

if (!string.IsNullOrWhiteSpace(settings.DefaultApiUserID))
{
if (!int.TryParse(settings.DefaultApiUserID, out var userId))
{
throw new Exception("Overseerr default user ID must be a number.");
}

response = await HttpGetAsync(httpClient, settings, $"{GetBaseURL(settings)}user/{userId}");

try
{
await response.ThrowIfNotSuccessfulAsync("OverseerrFindSpecificUser failed", x => x.error);
}
catch (System.Exception ex)
{
logger.LogWarning(ex, $"Default overseerr user with user id \"{userId}\" could not found: " + ex.Message);
throw new Exception($"Default overseerr user with user id \"{userId}\" could not found.");
}
}

testSuccessful = true;
}
catch (HttpRequestException ex)
Expand Down Expand Up @@ -154,7 +174,7 @@ public async Task<IReadOnlyList<Movie>> SearchMovieAsync(string movieName)
{
try
{
var response = await HttpGetAsync($"{BaseURL}search/?query={movieName}&page=1&language=en");
var response = await HttpGetAsync($"{BaseURL}search/?query={Uri.EscapeDataString(movieName)}&page=1&language=en");
await response.ThrowIfNotSuccessfulAsync("OverseerrMovieSearch failed", x => x.error);

var jsonResponse = await response.Content.ReadAsStringAsync();
Expand Down Expand Up @@ -231,7 +251,7 @@ async Task<IReadOnlyList<SearchedTvShow>> ITvShowSearcher.SearchTvShowAsync(stri
{
try
{
var response = await HttpGetAsync($"{BaseURL}search/?query={tvShowName}&page=1&language=en");
var response = await HttpGetAsync($"{BaseURL}search/?query={Uri.EscapeDataString(tvShowName)}&page=1&language=en");
await response.ThrowIfNotSuccessfulAsync("OverseerrTvShowSearch failed", x => x.error);

var jsonResponse = await response.Content.ReadAsStringAsync();
Expand Down Expand Up @@ -361,7 +381,7 @@ private async Task<JSONUserNotificationSettings> GetUserNotificationSettings(int
{
var response = await HttpGetAsync($"{BaseURL}user/{userId}/settings/notifications");
var jsonResponse = await response.Content.ReadAsStringAsync();
await response.ThrowIfNotSuccessfulAsync("OverseerrFindSpecificUsers failed", x => x.error);
await response.ThrowIfNotSuccessfulAsync("OverseerrFindSpecificUserNotifications failed", x => x.error);

return JsonConvert.DeserializeObject<JSONUserNotificationSettings>(jsonResponse);
}
Expand Down

0 comments on commit 27a84e2

Please sign in to comment.