mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-15 09:42:56 -07:00
Fixed signlar
This commit is contained in:
parent
f16b33c437
commit
15d34e0aaf
8 changed files with 71 additions and 41 deletions
39
src/Ombi.Hubs/NotificationHub.cs
Normal file
39
src/Ombi.Hubs/NotificationHub.cs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
namespace Ombi.Hubs
|
||||||
|
{
|
||||||
|
public class NotificationHub : Hub
|
||||||
|
{
|
||||||
|
public static ConcurrentDictionary<string, string> UsersOnline = new ConcurrentDictionary<string, string>();
|
||||||
|
|
||||||
|
public override Task OnConnectedAsync()
|
||||||
|
{
|
||||||
|
var identity = (ClaimsIdentity) Context.User.Identity;
|
||||||
|
var userIdClaim = identity.Claims.FirstOrDefault(x => x.Type.Equals("Id", StringComparison.InvariantCultureIgnoreCase));
|
||||||
|
if (userIdClaim == null)
|
||||||
|
{
|
||||||
|
return base.OnConnectedAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
UsersOnline.TryAdd(Context.ConnectionId, userIdClaim.Value);
|
||||||
|
return base.OnConnectedAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Task OnDisconnectedAsync(Exception exception)
|
||||||
|
{
|
||||||
|
UsersOnline.TryRemove(Context.ConnectionId, out _);
|
||||||
|
return base.OnDisconnectedAsync(exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Notification(string data)
|
||||||
|
{
|
||||||
|
return Clients.All.SendAsync("Notification", data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.SignalR;
|
|
||||||
|
|
||||||
namespace Ombi.Hubs
|
|
||||||
{
|
|
||||||
public class ScheduledJobsHub : Hub
|
|
||||||
{
|
|
||||||
public Task Send(string data)
|
|
||||||
{
|
|
||||||
return Clients.All.SendAsync("Send", data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -37,11 +37,12 @@ export class AppComponent implements OnInit {
|
||||||
public username: string;
|
public username: string;
|
||||||
|
|
||||||
private checkedForUpdate: boolean;
|
private checkedForUpdate: boolean;
|
||||||
|
private hubConnected: boolean;
|
||||||
|
|
||||||
|
|
||||||
@HostBinding('class') public componentCssClass;
|
@HostBinding('class') public componentCssClass;
|
||||||
|
|
||||||
private scheduleHubConnection: HubConnection | undefined;
|
private notificationHubConnection: HubConnection | undefined;
|
||||||
|
|
||||||
constructor(public notificationService: NotificationService,
|
constructor(public notificationService: NotificationService,
|
||||||
public authService: AuthService,
|
public authService: AuthService,
|
||||||
|
@ -117,27 +118,28 @@ export class AppComponent implements OnInit {
|
||||||
},
|
},
|
||||||
err => this.checkedForUpdate = true);
|
err => this.checkedForUpdate = true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.scheduleHubConnection = new signalR.HubConnectionBuilder().withUrl("/hubs/schedules", {
|
if (this.authService.loggedIn() && !this.hubConnected) {
|
||||||
|
this.notificationHubConnection = new signalR.HubConnectionBuilder().withUrl("/hubs/notification", {
|
||||||
accessTokenFactory: () => {
|
accessTokenFactory: () => {
|
||||||
return this.authService.getToken();
|
return this.authService.getToken();
|
||||||
}
|
}
|
||||||
})
|
}).configureLogging(signalR.LogLevel.Information).build();
|
||||||
.configureLogging(signalR.LogLevel.Information).build();
|
|
||||||
|
|
||||||
this.scheduleHubConnection
|
this.notificationHubConnection
|
||||||
.start()
|
.start()
|
||||||
.then(() => console.info('Connection started!'))
|
.then(() => this.hubConnected = true)
|
||||||
.catch(err => console.error(err));
|
.catch(err => console.error(err));
|
||||||
this.scheduleHubConnection.on("Send", (data: any) => {
|
this.notificationHubConnection.on("Notification", (data: any) => {
|
||||||
this.snackBar.open(data, "OK", {
|
this.snackBar.open(data, "OK", {
|
||||||
duration: 3000
|
duration: 3000
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public openMobileApp(event: any) {
|
public openMobileApp(event: any) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { InputSwitchModule, SidebarModule } from "primeng/primeng";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
MatButtonModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, MatTooltipModule, MatSelectModule, MatTableModule, MatPaginatorModule, MatSortModule,
|
MatButtonModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, MatTooltipModule, MatSelectModule, MatTableModule, MatPaginatorModule, MatSortModule,
|
||||||
MatTreeModule, MatStepperModule} from '@angular/material';
|
MatTreeModule, MatStepperModule, MatSnackBarModule} from '@angular/material';
|
||||||
import { MatCardModule, MatInputModule, MatTabsModule, MatAutocompleteModule, MatCheckboxModule, MatExpansionModule, MatDialogModule, MatProgressSpinnerModule,
|
import { MatCardModule, MatInputModule, MatTabsModule, MatAutocompleteModule, MatCheckboxModule, MatExpansionModule, MatDialogModule, MatProgressSpinnerModule,
|
||||||
MatChipsModule } from "@angular/material";
|
MatChipsModule } from "@angular/material";
|
||||||
import { EpisodeRequestComponent } from "./episode-request/episode-request.component";
|
import { EpisodeRequestComponent } from "./episode-request/episode-request.component";
|
||||||
|
|
|
@ -126,7 +126,8 @@ namespace Ombi.Controllers.V1
|
||||||
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
|
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
|
||||||
new Claim(ClaimTypes.NameIdentifier, user.Id),
|
new Claim(ClaimTypes.NameIdentifier, user.Id),
|
||||||
new Claim(ClaimTypes.Name, user.UserName),
|
new Claim(ClaimTypes.Name, user.UserName),
|
||||||
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
|
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||||||
|
new Claim("Id", user.Id)
|
||||||
};
|
};
|
||||||
claims.AddRange(roles.Select(role => new Claim("role", role)));
|
claims.AddRange(roles.Select(role => new Claim("role", role)));
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,12 @@ namespace Ombi.Controllers.V2
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class HubController : ControllerBase
|
public class HubController : ControllerBase
|
||||||
{
|
{
|
||||||
public HubController(IHubContext<ScheduledJobsHub> hub)
|
public HubController(IHubContext<NotificationHub> hub)
|
||||||
{
|
{
|
||||||
_hub = hub;
|
_hub = hub;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IHubContext<ScheduledJobsHub> _hub;
|
private readonly IHubContext<NotificationHub> _hub;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns search results for both TV and Movies
|
/// Returns search results for both TV and Movies
|
||||||
|
@ -34,7 +34,7 @@ namespace Ombi.Controllers.V2
|
||||||
[HttpGet("{searchTerm}")]
|
[HttpGet("{searchTerm}")]
|
||||||
public async Task MultiSearch(string searchTerm)
|
public async Task MultiSearch(string searchTerm)
|
||||||
{
|
{
|
||||||
await _hub.Clients.All.SendAsync("Send", searchTerm);
|
await _hub.Clients.All.SendAsync("Notification", searchTerm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -221,7 +221,7 @@ namespace Ombi
|
||||||
c.SwaggerEndpoint("/swagger/v2/swagger.json", "API V2");
|
c.SwaggerEndpoint("/swagger/v2/swagger.json", "API V2");
|
||||||
});
|
});
|
||||||
|
|
||||||
app.UseSignalR(routes => { routes.MapHub<ScheduledJobsHub>("/hubs/schedules"); });
|
app.UseSignalR(routes => { routes.MapHub<NotificationHub>("/hubs/notification"); });
|
||||||
|
|
||||||
app.UseMvcWithDefaultRoute();
|
app.UseMvcWithDefaultRoute();
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.Mvc.ApiExplorer;
|
using Microsoft.AspNetCore.Mvc.ApiExplorer;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
@ -144,12 +145,12 @@ namespace Ombi
|
||||||
{
|
{
|
||||||
OnMessageReceived = context =>
|
OnMessageReceived = context =>
|
||||||
{
|
{
|
||||||
var accessToken = context.Request.Headers["id_token"];
|
var accessToken = context.Request.Query["access_token"];
|
||||||
|
|
||||||
// If the request is for our hub...
|
// If the request is for our hub...
|
||||||
var path = context.HttpContext.Request.Path;
|
var path = context.HttpContext.Request.Path;
|
||||||
if (!string.IsNullOrEmpty(accessToken) &&
|
if (!string.IsNullOrEmpty(accessToken) &&
|
||||||
(path.StartsWithSegments("/hubs/")))
|
(path.StartsWithSegments("/hubs")))
|
||||||
{
|
{
|
||||||
// Read the token out of the query string
|
// Read the token out of the query string
|
||||||
context.Token = accessToken;
|
context.Token = accessToken;
|
||||||
|
@ -158,6 +159,7 @@ namespace Ombi
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue