mirror of
https://github.com/fergalmoran/podnoms.git
synced 2025-12-22 09:18:08 +00:00
SignalR auth working
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
"@angular/platform-browser": "6.0.0",
|
"@angular/platform-browser": "6.0.0",
|
||||||
"@angular/platform-browser-dynamic": "6.0.0",
|
"@angular/platform-browser-dynamic": "6.0.0",
|
||||||
"@angular/router": "6.0.0",
|
"@angular/router": "6.0.0",
|
||||||
|
"@aspnet/signalr": "^1.0.0-rtm-30751",
|
||||||
"@ngrx/effects": "^5.1.0",
|
"@ngrx/effects": "^5.1.0",
|
||||||
"@ngrx/store": "^5.1.0",
|
"@ngrx/store": "^5.1.0",
|
||||||
"@ngrx/store-devtools": "^5.1.0",
|
"@ngrx/store-devtools": "^5.1.0",
|
||||||
|
|||||||
@@ -23,12 +23,29 @@ export const ADD_SUCCESS = '[Chat] Add Chat Success';
|
|||||||
export const ADD_FAIL = '[Chat] Add Chat Fail';
|
export const ADD_FAIL = '[Chat] Add Chat Fail';
|
||||||
export class AddAction implements Action {
|
export class AddAction implements Action {
|
||||||
readonly type = ADD;
|
readonly type = ADD;
|
||||||
constructor(public payload: ChatModel) {
|
constructor(public payload: ChatModel) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
export class AddSuccessAction implements Action {
|
export class AddSuccessAction implements Action {
|
||||||
readonly type = ADD_SUCCESS;
|
readonly type = ADD_SUCCESS;
|
||||||
|
constructor(public payload: ChatModel) {}
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
//#region Add
|
||||||
|
// the receive action is for messages from signalR
|
||||||
|
// we don't want to initiate a POST to the server.
|
||||||
|
export const RECEIVE = '[Chat] Receive Chat';
|
||||||
|
export const RECEIVE_SUCCESS = '[Chat] Receive Chat Success';
|
||||||
|
export const RECEIVE_FAIL = '[Chat] Receive Chat Fail';
|
||||||
|
export class ReceiveAction implements Action {
|
||||||
|
readonly type = RECEIVE;
|
||||||
constructor(public payload: ChatModel) {
|
constructor(public payload: ChatModel) {
|
||||||
|
console.log('chat.actions', 'RECEIVE', payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class ReceiveSuccessAction implements Action {
|
||||||
|
readonly type = RECEIVE_SUCCESS;
|
||||||
|
constructor(public payload: ChatModel) {
|
||||||
|
console.log('chat.actions', 'RECEIVE_SUCESS', payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
@@ -37,5 +54,6 @@ export type Actions =
|
|||||||
| LoadSuccessAction
|
| LoadSuccessAction
|
||||||
| LoadFailAction
|
| LoadFailAction
|
||||||
| AddAction
|
| AddAction
|
||||||
| AddSuccessAction;
|
| AddSuccessAction
|
||||||
|
| ReceiveAction
|
||||||
|
| ReceiveSuccessAction;
|
||||||
|
|||||||
@@ -58,13 +58,11 @@ export class AppComponent implements OnInit {
|
|||||||
const chatterChannel = `${p.id}`;
|
const chatterChannel = `${p.id}`;
|
||||||
this._signalrService
|
this._signalrService
|
||||||
.init('userupdates')
|
.init('userupdates')
|
||||||
.then((r) => {
|
.then((listener) => {
|
||||||
this._signalrService.connection.on(
|
listener.on<string>(chatterChannel)
|
||||||
chatterChannel,
|
.subscribe(result => {
|
||||||
(result) => {
|
|
||||||
this._toastyService.info(result);
|
this._toastyService.info(result);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(
|
console.error(
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ export function provideConfig() {
|
|||||||
authDomain: 'podnoms-api.firebaseapp.com',
|
authDomain: 'podnoms-api.firebaseapp.com',
|
||||||
databaseURL: 'https://podnoms-api.firebaseio.com',
|
databaseURL: 'https://podnoms-api.firebaseio.com',
|
||||||
projectId: 'podnoms-api',
|
projectId: 'podnoms-api',
|
||||||
storageBucket: '',
|
storageBucket: 'podnoms-api.appspot.com',
|
||||||
messagingSenderId: '357461672895'
|
messagingSenderId: '357461672895'
|
||||||
}),
|
}),
|
||||||
AngularFireDatabaseModule,
|
AngularFireDatabaseModule,
|
||||||
|
|||||||
@@ -25,8 +25,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="chat-controls" *ngIf="!loading">
|
<div class="chat-controls">
|
||||||
<input class="message-input" placeholder="Type your message here..." type="text" #message (keyup.enter)="sendMessage(message)">
|
<input #message class="message-input" placeholder="Type your message and press enter..." type="text"
|
||||||
|
(keyup.enter)="sendMessage(message)">
|
||||||
<div class="chat-extra">
|
<div class="chat-extra">
|
||||||
<a href="#">
|
<a href="#">
|
||||||
<span class="extra-tooltip">Attach Document</span>
|
<span class="extra-tooltip">Attach Document</span>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, ViewChild, ElementRef } from '@angular/core';
|
||||||
import { ProfileService } from '../../services/profile.service';
|
import { ProfileService } from '../../services/profile.service';
|
||||||
import { SignalRService } from '../../services/signalr.service';
|
import { SignalRService } from '../../services/signalr.service';
|
||||||
import { ProfileModel } from 'app/models/profile.model';
|
import { ProfileModel } from 'app/models/profile.model';
|
||||||
@@ -15,11 +15,17 @@ import { Observable } from 'rxjs/Observable';
|
|||||||
templateUrl: './chat-widget.component.html',
|
templateUrl: './chat-widget.component.html',
|
||||||
styleUrls: ['./chat-widget.component.css']
|
styleUrls: ['./chat-widget.component.css']
|
||||||
})
|
})
|
||||||
export class ChatWidgetComponent implements OnInit {
|
export class ChatWidgetComponent {
|
||||||
chatActive: boolean = false;
|
chatActive: boolean = false;
|
||||||
loading: boolean = false;
|
private user: ProfileModel;
|
||||||
user: ProfileModel;
|
|
||||||
messages$: Observable<ChatModel[]>;
|
messages$: Observable<ChatModel[]>;
|
||||||
|
private messageEl: ElementRef;
|
||||||
|
|
||||||
|
// have to handle ViewChild like this as it's hidden with ngIf
|
||||||
|
@ViewChild('message')
|
||||||
|
set content(content: ElementRef) {
|
||||||
|
this.messageEl = content;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _profileService: ProfileService,
|
private _profileService: ProfileService,
|
||||||
@@ -28,25 +34,17 @@ export class ChatWidgetComponent implements OnInit {
|
|||||||
) {
|
) {
|
||||||
this._profileService.getProfile().subscribe((p) => (this.user = p));
|
this._profileService.getProfile().subscribe((p) => (this.user = p));
|
||||||
this.messages$ = _store.select(fromChat.getChat);
|
this.messages$ = _store.select(fromChat.getChat);
|
||||||
|
this.messages$.subscribe((r) => {
|
||||||
|
if (r.length != 0) {
|
||||||
|
this.chatActive = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {}
|
|
||||||
|
|
||||||
togglePopup() {
|
togglePopup() {
|
||||||
this.chatActive = !this.chatActive;
|
this.chatActive = !this.chatActive;
|
||||||
|
if (this.chatActive) {
|
||||||
if (this.chatActive && this.user) {
|
setTimeout(() => this.messageEl.nativeElement.focus(), 0);
|
||||||
this.loading = true;
|
|
||||||
this._signalRService.init('chat').then(() => {
|
|
||||||
this.loading = false;
|
|
||||||
this._signalRService.connection.on('SendMessage', (message) => {
|
|
||||||
console.log(
|
|
||||||
'chat-widget.component',
|
|
||||||
'SendMessage',
|
|
||||||
message
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import * as fromEntriesActions from 'app/actions/entries.actions';
|
|||||||
import { PodcastService } from '../../../services/podcast.service';
|
import { PodcastService } from '../../../services/podcast.service';
|
||||||
import { AudioService } from 'app/services/audio.service';
|
import { AudioService } from 'app/services/audio.service';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { AudioProcessingMessageModel } from 'app/models/audioprocessingmessage.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-entry-list-item]',
|
selector: '[app-entry-list-item]',
|
||||||
@@ -39,23 +40,22 @@ export class EntryListItemComponent implements OnInit {
|
|||||||
) {
|
) {
|
||||||
this._signalRService
|
this._signalRService
|
||||||
.init('audioprocessing')
|
.init('audioprocessing')
|
||||||
.then(() => {
|
.then((listener) => {
|
||||||
const updateChannel: string = `${
|
const updateChannel: string = `${
|
||||||
this.entry.uid
|
this.entry.uid
|
||||||
}__progress_update`;
|
}__progress_update`;
|
||||||
const processedChannel: string = `${
|
const processedChannel: string = `${
|
||||||
this.entry.uid
|
this.entry.uid
|
||||||
}__info_processed`;
|
}__info_processed`;
|
||||||
this._signalRService.connection.on(
|
listener
|
||||||
updateChannel,
|
.on<AudioProcessingMessageModel>(updateChannel)
|
||||||
(result) => {
|
.subscribe((result) => {
|
||||||
this.percentageProcessed = result.percentage;
|
this.percentageProcessed = result.percentage;
|
||||||
this.currentSpeed = result.currentSpeed;
|
this.currentSpeed = result.currentSpeed;
|
||||||
}
|
});
|
||||||
);
|
listener
|
||||||
this._signalRService.connection.on(
|
.on<PodcastEntryModel>(processedChannel)
|
||||||
processedChannel,
|
.subscribe((result) => {
|
||||||
(result) => {
|
|
||||||
this.entry = result;
|
this.entry = result;
|
||||||
if (this.entry.processingStatus === 'Processed') {
|
if (this.entry.processingStatus === 'Processed') {
|
||||||
// only update the store when we're finished.
|
// only update the store when we're finished.
|
||||||
@@ -65,8 +65,7 @@ export class EntryListItemComponent implements OnInit {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
})
|
})
|
||||||
.catch((err) =>
|
.catch((err) =>
|
||||||
console.error(
|
console.error(
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
import {
|
import { LoadAction, LOAD_FAIL } from './../actions/chat.actions';
|
||||||
LoadAction,
|
|
||||||
LOAD_FAIL
|
|
||||||
} from './../actions/chat.actions';
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Actions, Effect } from '@ngrx/effects';
|
import { Actions, Effect } from '@ngrx/effects';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
@@ -22,8 +19,8 @@ export class ChatEffects {
|
|||||||
.switchMap((payload: chat.LoadAction) =>
|
.switchMap((payload: chat.LoadAction) =>
|
||||||
this._service
|
this._service
|
||||||
.get()
|
.get()
|
||||||
.map(res => ({ type: chat.LOAD_SUCCESS, payload: res }))
|
.map((res) => ({ type: chat.LOAD_SUCCESS, payload: res }))
|
||||||
.catch(err => {
|
.catch((err) => {
|
||||||
console.error('ChatEffects', 'get$', err);
|
console.error('ChatEffects', 'get$', err);
|
||||||
return Observable.of({ type: chat.LOAD_FAIL });
|
return Observable.of({ type: chat.LOAD_FAIL });
|
||||||
})
|
})
|
||||||
@@ -31,8 +28,17 @@ export class ChatEffects {
|
|||||||
@Effect()
|
@Effect()
|
||||||
put$ = this.actions$
|
put$ = this.actions$
|
||||||
.ofType(chat.ADD)
|
.ofType(chat.ADD)
|
||||||
.switchMap((action: chat.AddAction) => this._service.send(action.payload))
|
.switchMap((action: chat.AddAction) =>
|
||||||
.map(res => ({ type: chat.ADD_SUCCESS, payload: res }));
|
this._service.send(action.payload)
|
||||||
|
)
|
||||||
|
.map((res) => ({ type: chat.ADD_SUCCESS, payload: res }));
|
||||||
|
@Effect()
|
||||||
|
receive$ = this.actions$
|
||||||
|
.ofType(chat.RECEIVE)
|
||||||
|
.map((res: chat.ReceiveAction) => ({ type: chat.RECEIVE_SUCCESS, payload: res.payload }));
|
||||||
|
// receive$ = this.actions$.ofType(chat.RECEIVE).map((res) => {
|
||||||
|
// return { type: chat.RECEIVE_SUCCESS, payload: res };
|
||||||
|
// });
|
||||||
|
|
||||||
constructor(private _service: ChatService, private actions$: Actions) {}
|
constructor(private _service: ChatService, private actions$: Actions) {}
|
||||||
}
|
}
|
||||||
|
|||||||
6
client/src/app/models/audioprocessingmessage.model.ts
Normal file
6
client/src/app/models/audioprocessingmessage.model.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export class AudioProcessingMessageModel {
|
||||||
|
percentage: number;
|
||||||
|
totalSize: string;
|
||||||
|
currentSpeed: string;
|
||||||
|
eTA: string;
|
||||||
|
}
|
||||||
@@ -33,7 +33,8 @@ export function reducer(state = initialState, action: chat.Actions): State {
|
|||||||
loading: false
|
loading: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case chat.ADD_SUCCESS: {
|
case chat.ADD_SUCCESS:
|
||||||
|
case chat.RECEIVE_SUCCESS: {
|
||||||
const newResults = _.clone(state.result);
|
const newResults = _.clone(state.result);
|
||||||
newResults.push(action.payload);
|
newResults.push(action.payload);
|
||||||
const newState = {
|
const newState = {
|
||||||
|
|||||||
@@ -4,11 +4,35 @@ import { Observable } from 'rxjs/Observable';
|
|||||||
import { environment } from 'environments/environment';
|
import { environment } from 'environments/environment';
|
||||||
import { ChatModel } from 'app/models/chat.model';
|
import { ChatModel } from 'app/models/chat.model';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { SignalRService } from './signalr.service';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
import * as fromChat from 'app/reducers';
|
||||||
|
import * as fromChatActions from 'app/actions/chat.actions';
|
||||||
|
import { ApplicationState } from '../store';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ChatService extends BaseService {
|
export class ChatService extends BaseService {
|
||||||
constructor(private _http: HttpClient) {
|
constructor(
|
||||||
|
private _http: HttpClient,
|
||||||
|
private _signalRService: SignalRService,
|
||||||
|
private _store: Store<ApplicationState>
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
|
this._signalRService.init('chat').then((listener) => {
|
||||||
|
listener
|
||||||
|
.on<ChatModel>('SendMessage')
|
||||||
|
.subscribe((message: ChatModel) => {
|
||||||
|
console.log(
|
||||||
|
'chat-widget.component',
|
||||||
|
'SendMessage',
|
||||||
|
message
|
||||||
|
);
|
||||||
|
this._store.dispatch(
|
||||||
|
new fromChatActions.ReceiveAction(message)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get(): Observable<ChatModel[]> {
|
get(): Observable<ChatModel[]> {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export class MessagingService {
|
|||||||
private _pushRegistrationServer: PushRegistrationService
|
private _pushRegistrationServer: PushRegistrationService
|
||||||
) {
|
) {
|
||||||
this.messaging.usePublicVapidKey(
|
this.messaging.usePublicVapidKey(
|
||||||
'BKyhUqIVZLauKNA-DXPXbIVLj5XiWurHbRV_0Rd3BOjY5cU9GOrd5ptXVJ2CNExxdveKYzZevrep2CflKeqkyqo'
|
'BP05eVFzqeEh54DaL3TOe6x_8UFs60nw_gfSrI5tdILjb5VnHwas0n7c_075tsc1w5fm87u9d4Dawj_YN13PSAI'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,37 @@
|
|||||||
import { PodnomsAuthService } from './podnoms-auth.service';
|
import { PodnomsAuthService } from './podnoms-auth.service';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import {
|
import { HubConnection, HubConnectionBuilder, LogLevel } from '@aspnet/signalr';
|
||||||
HubConnection,
|
|
||||||
HubConnectionBuilder,
|
|
||||||
JsonHubProtocol,
|
|
||||||
LogLevel
|
|
||||||
} from '@aspnet/signalr';
|
|
||||||
import { environment } from 'environments/environment';
|
import { environment } from 'environments/environment';
|
||||||
|
import { Observable, Subscriber } from 'rxjs';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SignalRService {
|
export class SignalRService {
|
||||||
public connection: HubConnection;
|
private _connected: boolean = false;
|
||||||
|
private _connection: HubConnection;
|
||||||
|
|
||||||
constructor(private _auth: PodnomsAuthService) {}
|
constructor(private _auth: PodnomsAuthService) {}
|
||||||
public init(hub: string): Promise<void> {
|
public init(hub: string): Promise<SignalRService> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
const url = `${environment.SIGNALR_HOST}/hubs/${hub}`;
|
const url = `${environment.SIGNALR_HOST}/hubs/${hub}`;
|
||||||
|
|
||||||
const token = this._auth.getToken();
|
const token = this._auth.getToken();
|
||||||
const options: any = {
|
this._connection = new HubConnectionBuilder()
|
||||||
transport: 0
|
.configureLogging(LogLevel.Debug)
|
||||||
};
|
.withUrl(url + '?token=' + token)
|
||||||
|
|
||||||
this.connection = new HubConnectionBuilder()
|
|
||||||
.configureLogging(LogLevel.Error)
|
|
||||||
.withUrl(url + '?token=' + token, options)
|
|
||||||
.withHubProtocol(new JsonHubProtocol())
|
|
||||||
.build();
|
.build();
|
||||||
return this.connection.start();
|
resolve(this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public on<T>(channel: string): Observable<T> {
|
||||||
|
const listener = new Observable<T>((subscriber: Subscriber<T>) => {
|
||||||
|
this._connection.on(channel, (message) => {
|
||||||
|
const result: T = message as T;
|
||||||
|
subscriber.next(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if (!this._connected) {
|
||||||
|
this._connection.start().then(() => (this._connected = true));
|
||||||
|
}
|
||||||
|
return listener;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,9 +32,6 @@
|
|||||||
ga('send', 'pageview');
|
ga('send', 'pageview');
|
||||||
</script>
|
</script>
|
||||||
<!-- End Google Analytics -->
|
<!-- End Google Analytics -->
|
||||||
<!-- Begin Crisp -->
|
|
||||||
<script type="text/javascript">window.$crisp = []; window.CRISP_WEBSITE_ID = "af7d6aa7-0cb8-4f74-89aa-7f3742058e85"; (function () { d = document; s = d.createElement("script"); s.src = "https://client.crisp.chat/l.js"; s.async = 1; d.getElementsByTagName("head")[0].appendChild(s); })();</script>
|
|
||||||
<!-- End Crisp -->
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Models.ViewModels;
|
using PodNoms.Api.Models.ViewModels;
|
||||||
using PodNoms.Api.Persistence;
|
using PodNoms.Api.Persistence;
|
||||||
using PodNoms.Api.Providers;
|
using PodNoms.Api.Providers;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Models.ViewModels;
|
using PodNoms.Api.Models.ViewModels;
|
||||||
using PodNoms.Api.Services;
|
using PodNoms.Api.Services;
|
||||||
using PodNoms.Api.Services.Auth;
|
using PodNoms.Api.Services.Auth;
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using PodNoms.Api.Services.Auth;
|
using PodNoms.Api.Services.Auth;
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
public class BaseAuthController : Controller {
|
public class BaseAuthController : Controller {
|
||||||
private readonly ClaimsPrincipal _caller;
|
private readonly ClaimsPrincipal _caller;
|
||||||
protected readonly UserManager<ApplicationUser> _userManager;
|
protected readonly UserManager<ApplicationUser> _userManager;
|
||||||
|
|||||||
@@ -1,29 +1,40 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Lib.Net.Http.WebPush;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Models.ViewModels;
|
using PodNoms.Api.Models.ViewModels;
|
||||||
|
using PodNoms.Api.Services;
|
||||||
using PodNoms.Api.Services.Auth;
|
using PodNoms.Api.Services.Auth;
|
||||||
using PodNoms.Api.Services.Hubs;
|
using PodNoms.Api.Services.Hubs;
|
||||||
|
using PodNoms.Api.Services.Push;
|
||||||
|
using WebPush = Lib.Net.Http.WebPush;
|
||||||
|
|
||||||
namespace PodNoms.Api.Controllers {
|
namespace PodNoms.Api.Controllers {
|
||||||
[Route("[controller]")]
|
[Route("[controller]")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class ChatController : BaseAuthController {
|
public class ChatController : BaseAuthController {
|
||||||
private readonly HubLifetimeManager<ChatHub> _hub;
|
private readonly ISupportChatService _supportChatService;
|
||||||
|
|
||||||
public ChatController(IHttpContextAccessor contextAccessor, UserManager<ApplicationUser> userManager,
|
public ChatController(IHttpContextAccessor contextAccessor, UserManager<ApplicationUser> userManager,
|
||||||
HubLifetimeManager<ChatHub> chatHubContext) :
|
ISupportChatService supportChatService) :
|
||||||
base(contextAccessor, userManager) {
|
base(contextAccessor, userManager) {
|
||||||
this._hub = chatHubContext;
|
this._supportChatService = supportChatService;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<ActionResult<ChatViewModel>> Post([FromBody]ChatViewModel message) {
|
public async Task<ActionResult<ChatViewModel>> Post([FromBody]ChatViewModel message) {
|
||||||
await this._hub.SendAllAsync("SendMessage", new object[] { message.Message });
|
//need to lookup the current support host and notify them
|
||||||
|
message.FromUserName = _applicationUser.FullName;
|
||||||
|
message.FromUserId = _applicationUser.Id;
|
||||||
|
if (await _supportChatService.InitiateSupportRequest(_userId, message)) {
|
||||||
return Ok(message);
|
return Ok(message);
|
||||||
}
|
}
|
||||||
|
return Accepted(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Microsoft.AspNetCore.SignalR;
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Persistence;
|
using PodNoms.Api.Persistence;
|
||||||
using PodNoms.Api.Services.Auth;
|
using PodNoms.Api.Services.Auth;
|
||||||
using PodNoms.Api.Services.Downloader;
|
using PodNoms.Api.Services.Downloader;
|
||||||
@@ -24,7 +25,7 @@ namespace PodNoms.Api.Controllers {
|
|||||||
public class DebugController : BaseAuthController {
|
public class DebugController : BaseAuthController {
|
||||||
private readonly StorageSettings _storageSettings;
|
private readonly StorageSettings _storageSettings;
|
||||||
private readonly AudioFileStorageSettings _audioFileStorageSettings;
|
private readonly AudioFileStorageSettings _audioFileStorageSettings;
|
||||||
private readonly ApplicationsSettings _applicationsSettings;
|
private readonly HelpersSettings _helpersSettings;
|
||||||
private readonly ImageFileStorageSettings _imageFileStorageSettings;
|
private readonly ImageFileStorageSettings _imageFileStorageSettings;
|
||||||
private readonly HubLifetimeManager<DebugHub> _hubManager;
|
private readonly HubLifetimeManager<DebugHub> _hubManager;
|
||||||
private readonly IPushSubscriptionStore _subscriptionStore;
|
private readonly IPushSubscriptionStore _subscriptionStore;
|
||||||
@@ -34,7 +35,7 @@ namespace PodNoms.Api.Controllers {
|
|||||||
|
|
||||||
public DebugController(IOptions<StorageSettings> settings, IOptions<AppSettings> appSettings,
|
public DebugController(IOptions<StorageSettings> settings, IOptions<AppSettings> appSettings,
|
||||||
HubLifetimeManager<DebugHub> hubManager,
|
HubLifetimeManager<DebugHub> hubManager,
|
||||||
IOptions<ApplicationsSettings> applicationsSettings,
|
IOptions<HelpersSettings> helpersSettings,
|
||||||
IOptions<AudioFileStorageSettings> audioFileStorageSettings,
|
IOptions<AudioFileStorageSettings> audioFileStorageSettings,
|
||||||
IOptions<ImageFileStorageSettings> imageFileStorageSettings,
|
IOptions<ImageFileStorageSettings> imageFileStorageSettings,
|
||||||
IPushSubscriptionStore subscriptionStore,
|
IPushSubscriptionStore subscriptionStore,
|
||||||
@@ -43,7 +44,7 @@ namespace PodNoms.Api.Controllers {
|
|||||||
IHttpContextAccessor contextAccessor) : base(contextAccessor, userManager) {
|
IHttpContextAccessor contextAccessor) : base(contextAccessor, userManager) {
|
||||||
this._appSettings = appSettings.Value;
|
this._appSettings = appSettings.Value;
|
||||||
this._storageSettings = settings.Value;
|
this._storageSettings = settings.Value;
|
||||||
this._applicationsSettings = applicationsSettings.Value;
|
this._helpersSettings = helpersSettings.Value;
|
||||||
this._audioFileStorageSettings = audioFileStorageSettings.Value;
|
this._audioFileStorageSettings = audioFileStorageSettings.Value;
|
||||||
this._imageFileStorageSettings = imageFileStorageSettings.Value;
|
this._imageFileStorageSettings = imageFileStorageSettings.Value;
|
||||||
this._hubManager = hubManager;
|
this._hubManager = hubManager;
|
||||||
@@ -59,8 +60,8 @@ namespace PodNoms.Api.Controllers {
|
|||||||
CdnUrl = _storageSettings.CdnUrl,
|
CdnUrl = _storageSettings.CdnUrl,
|
||||||
AudioContainer = _audioFileStorageSettings.ContainerName,
|
AudioContainer = _audioFileStorageSettings.ContainerName,
|
||||||
ImageContainer = _imageFileStorageSettings.ContainerName,
|
ImageContainer = _imageFileStorageSettings.ContainerName,
|
||||||
YouTubeDlPath = _applicationsSettings.Downloader,
|
YouTubeDlPath = _helpersSettings.Downloader,
|
||||||
YouTubeDlVersion = AudioDownloader.GetVersion(_applicationsSettings.Downloader),
|
YouTubeDlVersion = AudioDownloader.GetVersion(_helpersSettings.Downloader),
|
||||||
OSVersion = System.Environment.OSVersion,
|
OSVersion = System.Environment.OSVersion,
|
||||||
RssUrl = _appSettings.RssUrl
|
RssUrl = _appSettings.RssUrl
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,12 +7,14 @@ using AutoMapper;
|
|||||||
using Hangfire;
|
using Hangfire;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Models.ViewModels;
|
using PodNoms.Api.Models.ViewModels;
|
||||||
using PodNoms.Api.Persistence;
|
using PodNoms.Api.Persistence;
|
||||||
using PodNoms.Api.Services;
|
using PodNoms.Api.Services;
|
||||||
@@ -24,6 +26,7 @@ using PodNoms.Api.Utils.RemoteParsers;
|
|||||||
|
|
||||||
namespace PodNoms.Api.Controllers {
|
namespace PodNoms.Api.Controllers {
|
||||||
[Route("[controller]")]
|
[Route("[controller]")]
|
||||||
|
[Authorize]
|
||||||
public class EntryController : BaseAuthController {
|
public class EntryController : BaseAuthController {
|
||||||
private readonly IPodcastRepository _podcastRepository;
|
private readonly IPodcastRepository _podcastRepository;
|
||||||
private readonly IEntryRepository _repository;
|
private readonly IEntryRepository _repository;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ using SixLabors.ImageSharp.PixelFormats;
|
|||||||
using SixLabors.ImageSharp.Processing;
|
using SixLabors.ImageSharp.Processing;
|
||||||
using SixLabors.ImageSharp.Processing.Transforms;
|
using SixLabors.ImageSharp.Processing.Transforms;
|
||||||
using SixLabors.ImageSharp.Processing.Filters;
|
using SixLabors.ImageSharp.Processing.Filters;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
|
|
||||||
namespace PodNoms.Api.Controllers {
|
namespace PodNoms.Api.Controllers {
|
||||||
[Authorize]
|
[Authorize]
|
||||||
@@ -42,6 +43,7 @@ namespace PodNoms.Api.Controllers {
|
|||||||
this._fileUploader = fileUploader;
|
this._fileUploader = fileUploader;
|
||||||
this._imageFileStorageSettings = imageFileStorageSettings.Value;
|
this._imageFileStorageSettings = imageFileStorageSettings.Value;
|
||||||
this._repository = repository;
|
this._repository = repository;
|
||||||
|
//this._repository = repository;
|
||||||
this._unitOfWork = unitOfWork;
|
this._unitOfWork = unitOfWork;
|
||||||
this._mapper = mapper;
|
this._mapper = mapper;
|
||||||
this._logger = loggerFactory.CreateLogger<ImageUploadController>();
|
this._logger = loggerFactory.CreateLogger<ImageUploadController>();
|
||||||
|
|||||||
@@ -23,17 +23,14 @@ namespace PodNoms.Api.Controllers {
|
|||||||
[Route("[controller]")]
|
[Route("[controller]")]
|
||||||
public class PodcastController : BaseAuthController {
|
public class PodcastController : BaseAuthController {
|
||||||
private readonly IPodcastRepository _repository;
|
private readonly IPodcastRepository _repository;
|
||||||
private readonly IOptions<AppSettings> _settings;
|
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
private readonly IUnitOfWork _uow;
|
private readonly IUnitOfWork _uow;
|
||||||
|
|
||||||
public PodcastController(IPodcastRepository repository, IOptions<AppSettings> options,
|
public PodcastController(IPodcastRepository repository, IMapper mapper, IUnitOfWork unitOfWork,
|
||||||
IMapper mapper, IUnitOfWork unitOfWork,
|
|
||||||
UserManager<ApplicationUser> userManager, IHttpContextAccessor contextAccessor)
|
UserManager<ApplicationUser> userManager, IHttpContextAccessor contextAccessor)
|
||||||
: base(contextAccessor, userManager) {
|
: base(contextAccessor, userManager) {
|
||||||
this._uow = unitOfWork;
|
this._uow = unitOfWork;
|
||||||
this._repository = repository;
|
this._repository = repository;
|
||||||
this._settings = options;
|
|
||||||
this._mapper = mapper;
|
this._mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Models.ViewModels.RssViewModels;
|
using PodNoms.Api.Models.ViewModels.RssViewModels;
|
||||||
using PodNoms.Api.Persistence;
|
using PodNoms.Api.Persistence;
|
||||||
using PodNoms.Api.Services.Auth;
|
using PodNoms.Api.Services.Auth;
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace PodNoms.Api.Models
|
|
||||||
{
|
|
||||||
public class ImageFileStorageSettings : FileStorageSettings
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AudioFileStorageSettings : FileStorageSettings
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FileStorageSettings
|
|
||||||
{
|
|
||||||
public string ContainerName { get; set; }
|
|
||||||
public long MaxUploadFileSize { get; set; }
|
|
||||||
public string[] AllowedFileTypes { get; set; }
|
|
||||||
|
|
||||||
public bool IsSupported(string fileName)
|
|
||||||
{
|
|
||||||
return AllowedFileTypes.Any(s => s == Path.GetExtension(fileName).ToLower());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class ApplicationsSettings
|
|
||||||
{
|
|
||||||
public string Downloader { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
namespace PodNoms.Api.Models {
|
namespace PodNoms.Api.Models.Settings {
|
||||||
public class AppSettings {
|
public class AppSettings {
|
||||||
public string Version { get; set; }
|
public string Version { get; set; }
|
||||||
public string SiteUrl { get; set; }
|
public string SiteUrl { get; set; }
|
||||||
public string RssUrl { get; set; }
|
public string RssUrl { get; set; }
|
||||||
public string GoogleApiKey { get; set; }
|
public string GoogleApiKey { get; set; }
|
||||||
|
public string Downloader { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
5
server/Models/Settings/ApplicationsSettings.cs
Normal file
5
server/Models/Settings/ApplicationsSettings.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
namespace PodNoms.Api.Models.Settings {
|
||||||
|
public class HelpersSettings {
|
||||||
|
public string Downloader { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
4
server/Models/Settings/AudioFileStorageSettings.cs
Normal file
4
server/Models/Settings/AudioFileStorageSettings.cs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
namespace PodNoms.Api.Models.Settings {
|
||||||
|
public class AudioFileStorageSettings : FileStorageSettings {
|
||||||
|
}
|
||||||
|
}
|
||||||
5
server/Models/Settings/ChatSettings.cs
Normal file
5
server/Models/Settings/ChatSettings.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
namespace PodNoms.Api.Models.Settings {
|
||||||
|
public class ChatSettings {
|
||||||
|
public string CurrentChatUser { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace PodNoms.Api.Models {
|
namespace PodNoms.Api.Models.Settings {
|
||||||
|
|
||||||
public class EmailSettings {
|
public class EmailSettings {
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
15
server/Models/Settings/FileStorageSettings.cs
Normal file
15
server/Models/Settings/FileStorageSettings.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Models.Settings {
|
||||||
|
|
||||||
|
public class FileStorageSettings {
|
||||||
|
public string ContainerName { get; set; }
|
||||||
|
public long MaxUploadFileSize { get; set; }
|
||||||
|
public string[] AllowedFileTypes { get; set; }
|
||||||
|
|
||||||
|
public bool IsSupported(string fileName) {
|
||||||
|
return AllowedFileTypes.Any(s => s == Path.GetExtension(fileName).ToLower());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
4
server/Models/Settings/ImageFileStorageSettings.cs
Normal file
4
server/Models/Settings/ImageFileStorageSettings.cs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
namespace PodNoms.Api.Models.Settings {
|
||||||
|
public class ImageFileStorageSettings : FileStorageSettings {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace PodNoms.Api.Models {
|
namespace PodNoms.Api.Models.Settings {
|
||||||
public class StorageSettings {
|
public class StorageSettings {
|
||||||
public string ConnectionString { get; set; }
|
public string ConnectionString { get; set; }
|
||||||
public string CdnUrl { get; set; }
|
public string CdnUrl { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
namespace PodNoms.Api.Models.ViewModels {
|
namespace PodNoms.Api.Models.ViewModels {
|
||||||
public class ChatViewModel {
|
public class ChatViewModel {
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
|
public string FromUserId { get; set; }
|
||||||
|
public string FromUserName { get; set; }
|
||||||
|
public string ToUserId { get; set; }
|
||||||
|
public string ToUserName { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
namespace PodNoms.Api.Models.ViewModels
|
namespace PodNoms.Api.Models.ViewModels {
|
||||||
{
|
|
||||||
public class ProcessProgressEvent {
|
public class ProcessProgressEvent {
|
||||||
public double Percentage { get; set; }
|
public double Percentage { get; set; }
|
||||||
public string TotalSize;
|
public string TotalSize;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Persistence;
|
using PodNoms.Api.Persistence;
|
||||||
using PodNoms.Api.Services.Storage;
|
using PodNoms.Api.Services.Storage;
|
||||||
using PodNoms.Api.Utils;
|
using PodNoms.Api.Utils;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<PackageReference Include="Hangfire" Version="1.6.17" />
|
<PackageReference Include="Hangfire" Version="1.6.17" />
|
||||||
<PackageReference Include="Hangfire.MemoryStorage" Version="1.5.2" />
|
<PackageReference Include="Hangfire.MemoryStorage" Version="1.5.2" />
|
||||||
<PackageReference Include="Lib.Net.Http.WebPush" Version="1.3.0" />
|
<PackageReference Include="Lib.Net.Http.WebPush" Version="1.3.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0-preview2-final" />
|
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0-rc1-final" />
|
||||||
<PackageReference Include="AutoMapper" Version="6.2.2" />
|
<PackageReference Include="AutoMapper" Version="6.2.2" />
|
||||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="3.2.0" />
|
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="3.2.0" />
|
||||||
<PackageReference Include="Handlebars.NetStandard" Version="1.8.1" />
|
<PackageReference Include="Handlebars.NetStandard" Version="1.8.1" />
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-dev001179" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-dev001179" />
|
||||||
<PackageReference Include="SQLitePCLRaw.bundle_green" Version="1.1.10-pre20180223200113" />
|
<PackageReference Include="SQLitePCLRaw.bundle_green" Version="1.1.10-pre20180223200113" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="2.3.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="2.3.0" />
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0-preview2-26406-04" />
|
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0-rc1" />
|
||||||
<PackageReference Include="WindowsAzure.Storage" Version="8.2.1" />
|
<PackageReference Include="WindowsAzure.Storage" Version="8.2.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -8,5 +8,6 @@ namespace PodNoms.Api.Services.Auth {
|
|||||||
public long? FacebookId { get; set; }
|
public long? FacebookId { get; set; }
|
||||||
public string PictureUrl { get; set; }
|
public string PictureUrl { get; set; }
|
||||||
public string Slug { get; set; }
|
public string Slug { get; set; }
|
||||||
|
public string FullName { get => $"{FirstName} {LastName}"; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace PodNoms.Api.Services.Auth
|
namespace PodNoms.Api.Services.Auth {
|
||||||
{
|
public static class ClaimsPrincipalExtensions {
|
||||||
public static class ClaimsPrincipalExtensions
|
public static string GetUserId(this ClaimsPrincipal principal) {
|
||||||
{
|
|
||||||
public static string GetUserId(this ClaimsPrincipal principal)
|
|
||||||
{
|
|
||||||
if (principal == null)
|
if (principal == null)
|
||||||
throw new ArgumentNullException(nameof(principal));
|
throw new ArgumentNullException(nameof(principal));
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using PodNoms.Api.Services.Gravatar;
|
using PodNoms.Api.Services.Gravatar;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
using PodNoms.Api.Utils;
|
using PodNoms.Api.Utils;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
|
|
||||||
namespace PodNoms.Api.Services.Auth {
|
namespace PodNoms.Api.Services.Auth {
|
||||||
public class PodNomsUserManager : UserManager<ApplicationUser> {
|
public class PodNomsUserManager : UserManager<ApplicationUser> {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
@@ -7,15 +8,12 @@ namespace PodNoms.Api.Services.Hubs {
|
|||||||
[Authorize]
|
[Authorize]
|
||||||
public class ChatHub : Hub {
|
public class ChatHub : Hub {
|
||||||
public override async Task OnConnectedAsync() {
|
public override async Task OnConnectedAsync() {
|
||||||
await Clients.All.SendAsync("SendAction", Context.User.Identity.Name, "joined");
|
// await Clients.All.SendAsync("SendAction", Context.User.Identity.Name, "joined");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task OnDisconnectedAsync(Exception ex) {
|
public override async Task OnDisconnectedAsync(Exception ex) {
|
||||||
await Clients.All.SendAsync("SendAction", Context.User.Identity.Name, "left");
|
// await Clients.All.SendAsync("SendAction", Context.User.Identity.Name, "left");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Send(string message) {
|
|
||||||
await Clients.All.SendAsync("SendMessage", Context.User.Identity.Name, message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
8
server/Services/ISupportChatService.cs
Normal file
8
server/Services/ISupportChatService.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using PodNoms.Api.Models.ViewModels;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Services {
|
||||||
|
public interface ISupportChatService {
|
||||||
|
Task<bool> InitiateSupportRequest(string fromUser, ChatViewModel message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ using Microsoft.Extensions.Options;
|
|||||||
using Microsoft.WindowsAzure.Storage;
|
using Microsoft.WindowsAzure.Storage;
|
||||||
using Microsoft.WindowsAzure.Storage.Blob;
|
using Microsoft.WindowsAzure.Storage.Blob;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Persistence;
|
using PodNoms.Api.Persistence;
|
||||||
|
|
||||||
namespace PodNoms.Api.Services.Jobs {
|
namespace PodNoms.Api.Services.Jobs {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ namespace PodNoms.Api.Services.Jobs {
|
|||||||
IPushNotificationService notificationService) {
|
IPushNotificationService notificationService) {
|
||||||
this._notificationService = notificationService;
|
this._notificationService = notificationService;
|
||||||
this._subscriptionStore = subscriptionStore;
|
this._subscriptionStore = subscriptionStore;
|
||||||
|
|
||||||
}
|
}
|
||||||
public async Task NotifyUser(string userId, string title, string body, string image) {
|
public async Task NotifyUser(string userId, string title, string body, string image) {
|
||||||
WebPush.PushMessage pushMessage = new WebPush.PushMessage(body) {
|
WebPush.PushMessage pushMessage = new WebPush.PushMessage(body) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Microsoft.Extensions.Configuration;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Persistence;
|
using PodNoms.Api.Persistence;
|
||||||
using PodNoms.Api.Services.Downloader;
|
using PodNoms.Api.Services.Downloader;
|
||||||
using PodNoms.Api.Services.Processor;
|
using PodNoms.Api.Services.Processor;
|
||||||
@@ -16,12 +17,12 @@ namespace PodNoms.Api.Services.Jobs {
|
|||||||
private readonly IAudioUploadProcessService _uploadService;
|
private readonly IAudioUploadProcessService _uploadService;
|
||||||
private readonly IConfiguration _options;
|
private readonly IConfiguration _options;
|
||||||
private readonly IPodcastRepository _podcastRepository;
|
private readonly IPodcastRepository _podcastRepository;
|
||||||
private readonly ApplicationsSettings _applicationsSettings;
|
private readonly HelpersSettings _helpersSettings;
|
||||||
private readonly ILogger<ProcessPlaylistItemJob> _logger;
|
private readonly ILogger<ProcessPlaylistItemJob> _logger;
|
||||||
private readonly IUnitOfWork _unitOfWork;
|
private readonly IUnitOfWork _unitOfWork;
|
||||||
public ProcessPlaylistItemJob(IPlaylistRepository playlistRepository, IEntryRepository entryRepository,
|
public ProcessPlaylistItemJob(IPlaylistRepository playlistRepository, IEntryRepository entryRepository,
|
||||||
IAudioUploadProcessService uploadService, IConfiguration options,
|
IAudioUploadProcessService uploadService, IConfiguration options,
|
||||||
IPodcastRepository podcastRepository, IOptions<ApplicationsSettings> applicationsSettings,
|
IPodcastRepository podcastRepository, IOptions<HelpersSettings> _helpersSettings,
|
||||||
IUnitOfWork unitOfWork, ILogger<ProcessPlaylistItemJob> logger) {
|
IUnitOfWork unitOfWork, ILogger<ProcessPlaylistItemJob> logger) {
|
||||||
this._unitOfWork = unitOfWork;
|
this._unitOfWork = unitOfWork;
|
||||||
this._playlistRepository = playlistRepository;
|
this._playlistRepository = playlistRepository;
|
||||||
@@ -29,7 +30,7 @@ namespace PodNoms.Api.Services.Jobs {
|
|||||||
this._uploadService = uploadService;
|
this._uploadService = uploadService;
|
||||||
this._options = options;
|
this._options = options;
|
||||||
this._podcastRepository = podcastRepository;
|
this._podcastRepository = podcastRepository;
|
||||||
this._applicationsSettings = applicationsSettings.Value;
|
this._helpersSettings = _helpersSettings.Value;
|
||||||
this._logger = logger;
|
this._logger = logger;
|
||||||
}
|
}
|
||||||
public async Task Execute() {
|
public async Task Execute() {
|
||||||
@@ -42,7 +43,7 @@ namespace PodNoms.Api.Services.Jobs {
|
|||||||
var item = await _playlistRepository.GetParsedItem(itemId, playlistId);
|
var item = await _playlistRepository.GetParsedItem(itemId, playlistId);
|
||||||
if (item != null && !string.IsNullOrEmpty(item.VideoType) && item.VideoType.Equals("youtube")) {
|
if (item != null && !string.IsNullOrEmpty(item.VideoType) && item.VideoType.Equals("youtube")) {
|
||||||
var url = $"https://www.youtube.com/watch?v={item.VideoId}";
|
var url = $"https://www.youtube.com/watch?v={item.VideoId}";
|
||||||
var downloader = new AudioDownloader(url, _applicationsSettings.Downloader);
|
var downloader = new AudioDownloader(url, _helpersSettings.Downloader);
|
||||||
var info = downloader.GetInfo();
|
var info = downloader.GetInfo();
|
||||||
if (info == AudioType.Valid) {
|
if (info == AudioType.Valid) {
|
||||||
var podcast = await _podcastRepository.GetAsync(item.Playlist.PodcastId);
|
var podcast = await _podcastRepository.GetAsync(item.Playlist.PodcastId);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using NYoutubeDL.Models;
|
using NYoutubeDL.Models;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Persistence;
|
using PodNoms.Api.Persistence;
|
||||||
using PodNoms.Api.Services.Downloader;
|
using PodNoms.Api.Services.Downloader;
|
||||||
using PodNoms.Api.Utils.RemoteParsers;
|
using PodNoms.Api.Utils.RemoteParsers;
|
||||||
@@ -17,21 +18,21 @@ namespace PodNoms.Api.Services.Jobs {
|
|||||||
public class ProcessPlaylistsJob : IJob {
|
public class ProcessPlaylistsJob : IJob {
|
||||||
public readonly IPlaylistRepository _playlistRepository;
|
public readonly IPlaylistRepository _playlistRepository;
|
||||||
public readonly IEntryRepository _entryRepository;
|
public readonly IEntryRepository _entryRepository;
|
||||||
private readonly ApplicationsSettings _applicationsSettings;
|
private readonly HelpersSettings _helpersSettings;
|
||||||
private readonly ILogger<ProcessPlaylistsJob> _logger;
|
private readonly ILogger<ProcessPlaylistsJob> _logger;
|
||||||
private readonly YouTubeParser _youTubeParser;
|
private readonly YouTubeParser _youTubeParser;
|
||||||
private readonly MixcloudParser _mixcloudParser;
|
private readonly MixcloudParser _mixcloudParser;
|
||||||
private readonly IUnitOfWork _unitOfWork;
|
private readonly IUnitOfWork _unitOfWork;
|
||||||
|
|
||||||
public ProcessPlaylistsJob(IPlaylistRepository playlistRepository, IEntryRepository entryRepository,
|
public ProcessPlaylistsJob(IPlaylistRepository playlistRepository, IEntryRepository entryRepository,
|
||||||
IUnitOfWork unitOfWork, IOptions<ApplicationsSettings> applicationsSettings,
|
IUnitOfWork unitOfWork, IOptions<HelpersSettings> helpersSettings,
|
||||||
ILoggerFactory logger, YouTubeParser youTubeParser, MixcloudParser mixcloudParser) {
|
ILoggerFactory logger, YouTubeParser youTubeParser, MixcloudParser mixcloudParser) {
|
||||||
this._unitOfWork = unitOfWork;
|
this._unitOfWork = unitOfWork;
|
||||||
this._youTubeParser = youTubeParser;
|
this._youTubeParser = youTubeParser;
|
||||||
this._mixcloudParser = mixcloudParser;
|
this._mixcloudParser = mixcloudParser;
|
||||||
this._playlistRepository = playlistRepository;
|
this._playlistRepository = playlistRepository;
|
||||||
this._entryRepository = entryRepository;
|
this._entryRepository = entryRepository;
|
||||||
this._applicationsSettings = applicationsSettings.Value;
|
this._helpersSettings = helpersSettings.Value;
|
||||||
this._logger = logger.CreateLogger<ProcessPlaylistsJob>();
|
this._logger = logger.CreateLogger<ProcessPlaylistsJob>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ namespace PodNoms.Api.Services.Jobs {
|
|||||||
var resultList = new List<ParsedItemResult>();
|
var resultList = new List<ParsedItemResult>();
|
||||||
|
|
||||||
foreach (var playlist in playlists) {
|
foreach (var playlist in playlists) {
|
||||||
var downloader = new AudioDownloader(playlist.SourceUrl, _applicationsSettings.Downloader);
|
var downloader = new AudioDownloader(playlist.SourceUrl, _helpersSettings.Downloader);
|
||||||
var info = downloader.GetInfo();
|
var info = downloader.GetInfo();
|
||||||
var id = ((PlaylistDownloadInfo)downloader.RawProperties).Id;
|
var id = ((PlaylistDownloadInfo)downloader.RawProperties).Id;
|
||||||
if (info == AudioType.Playlist && downloader.RawProperties is PlaylistDownloadInfo) {
|
if (info == AudioType.Playlist && downloader.RawProperties is PlaylistDownloadInfo) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using PodNoms.Api.Models;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using PodNoms.Api.Utils;
|
using PodNoms.Api.Utils;
|
||||||
using HandlebarsDotNet;
|
using HandlebarsDotNet;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
|
|
||||||
namespace PodNoms.Api.Services {
|
namespace PodNoms.Api.Services {
|
||||||
public class MailgunSender : IMailSender {
|
public class MailgunSender : IMailSender {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Models.ViewModels;
|
using PodNoms.Api.Models.ViewModels;
|
||||||
using PodNoms.Api.Persistence;
|
using PodNoms.Api.Persistence;
|
||||||
using PodNoms.Api.Services.Realtime;
|
using PodNoms.Api.Services.Realtime;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using Newtonsoft.Json;
|
|||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Serialization;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Models.ViewModels;
|
using PodNoms.Api.Models.ViewModels;
|
||||||
using PodNoms.Api.Persistence;
|
using PodNoms.Api.Persistence;
|
||||||
using PodNoms.Api.Services.Downloader;
|
using PodNoms.Api.Services.Downloader;
|
||||||
@@ -23,14 +24,14 @@ namespace PodNoms.Api.Services.Processor {
|
|||||||
private readonly IUnitOfWork _unitOfWork;
|
private readonly IUnitOfWork _unitOfWork;
|
||||||
private readonly IEntryRepository _repository;
|
private readonly IEntryRepository _repository;
|
||||||
|
|
||||||
public ApplicationsSettings _applicationsSettings { get; }
|
public HelpersSettings _helpersSettings { get; }
|
||||||
private readonly HubLifetimeManager<UserUpdatesHub> _userUpdateHub;
|
private readonly HubLifetimeManager<UserUpdatesHub> _userUpdateHub;
|
||||||
|
|
||||||
public UrlProcessService(IEntryRepository repository, IUnitOfWork unitOfWork,
|
public UrlProcessService(IEntryRepository repository, IUnitOfWork unitOfWork,
|
||||||
IFileUploader fileUploader, IOptions<ApplicationsSettings> applicationsSettings,
|
IFileUploader fileUploader, IOptions<HelpersSettings> helpersSettings,
|
||||||
HubLifetimeManager<UserUpdatesHub> userUpdateHub,
|
HubLifetimeManager<UserUpdatesHub> userUpdateHub,
|
||||||
ILoggerFactory logger, IMapper mapper, IRealTimeUpdater pusher) : base(logger, mapper, pusher) {
|
ILoggerFactory logger, IMapper mapper, IRealTimeUpdater pusher) : base(logger, mapper, pusher) {
|
||||||
this._applicationsSettings = applicationsSettings.Value;
|
this._helpersSettings = helpersSettings.Value;
|
||||||
this._repository = repository;
|
this._repository = repository;
|
||||||
this._unitOfWork = unitOfWork;
|
this._unitOfWork = unitOfWork;
|
||||||
this._userUpdateHub = userUpdateHub;
|
this._userUpdateHub = userUpdateHub;
|
||||||
@@ -56,7 +57,7 @@ namespace PodNoms.Api.Services.Processor {
|
|||||||
|
|
||||||
public async Task<AudioType> GetInformation(PodcastEntry entry) {
|
public async Task<AudioType> GetInformation(PodcastEntry entry) {
|
||||||
|
|
||||||
var downloader = new AudioDownloader(entry.SourceUrl, _applicationsSettings.Downloader);
|
var downloader = new AudioDownloader(entry.SourceUrl, _helpersSettings.Downloader);
|
||||||
var ret = downloader.GetInfo();
|
var ret = downloader.GetInfo();
|
||||||
if (ret == AudioType.Valid) {
|
if (ret == AudioType.Valid) {
|
||||||
entry.Title = downloader.Properties?.Title;
|
entry.Title = downloader.Properties?.Title;
|
||||||
@@ -81,7 +82,7 @@ namespace PodNoms.Api.Services.Processor {
|
|||||||
if (entry == null)
|
if (entry == null)
|
||||||
return false;
|
return false;
|
||||||
try {
|
try {
|
||||||
var downloader = new AudioDownloader(entry.SourceUrl, _applicationsSettings.Downloader);
|
var downloader = new AudioDownloader(entry.SourceUrl, _helpersSettings.Downloader);
|
||||||
var outputFile =
|
var outputFile =
|
||||||
Path.Combine(System.IO.Path.GetTempPath(), $"{System.Guid.NewGuid().ToString()}.mp3");
|
Path.Combine(System.IO.Path.GetTempPath(), $"{System.Guid.NewGuid().ToString()}.mp3");
|
||||||
|
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ namespace PodNoms.Api.Services.Push {
|
|||||||
private readonly ILogger<PushServicePushNotificationService> _logger;
|
private readonly ILogger<PushServicePushNotificationService> _logger;
|
||||||
private readonly IHttpClientFactory _httpClientFactory;
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
public string PublicKey => _options.PublicKey;
|
public string PublicKey => _options.PublicKey;
|
||||||
public FirebasePushNotificationService(IOptions<PushNotificationServiceOptions> optionsAccessor,
|
public FirebasePushNotificationService(IOptions<PushNotificationServiceOptions> pushOptions,
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
ILogger<PushServicePushNotificationService> logger) {
|
ILogger<PushServicePushNotificationService> logger) {
|
||||||
_options = optionsAccessor.Value;
|
_options = pushOptions.Value;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_httpClientFactory = httpClientFactory;
|
_httpClientFactory = httpClientFactory;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Microsoft.Extensions.Options;
|
|||||||
using Microsoft.WindowsAzure.Storage;
|
using Microsoft.WindowsAzure.Storage;
|
||||||
using Microsoft.WindowsAzure.Storage.Blob;
|
using Microsoft.WindowsAzure.Storage.Blob;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Services.Processor;
|
using PodNoms.Api.Services.Processor;
|
||||||
using PodNoms.Api.Services.Realtime;
|
using PodNoms.Api.Services.Realtime;
|
||||||
using PodNoms.Api.Utils.Extensions;
|
using PodNoms.Api.Utils.Extensions;
|
||||||
|
|||||||
55
server/Services/SupportChatService.cs
Normal file
55
server/Services/SupportChatService.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Lib.Net.Http.WebPush;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
|
using PodNoms.Api.Models.ViewModels;
|
||||||
|
using PodNoms.Api.Services.Auth;
|
||||||
|
using PodNoms.Api.Services.Hubs;
|
||||||
|
using PodNoms.Api.Services.Push;
|
||||||
|
using WebPush = Lib.Net.Http.WebPush;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Services {
|
||||||
|
public class SupportChatService : ISupportChatService {
|
||||||
|
private readonly ChatSettings _chatSettings;
|
||||||
|
private readonly IPushNotificationService _notificationService;
|
||||||
|
private readonly HubLifetimeManager<ChatHub> _chatHub;
|
||||||
|
private readonly UserManager<ApplicationUser> _userManager;
|
||||||
|
private readonly IPushSubscriptionStore _subscriptionStore;
|
||||||
|
private readonly HubLifetimeManager<ChatHub> _hub;
|
||||||
|
public SupportChatService(UserManager<ApplicationUser> userManager, IOptions<ChatSettings> chatSettings,
|
||||||
|
IPushSubscriptionStore subscriptionStore, IPushNotificationService notificationService,
|
||||||
|
HubLifetimeManager<ChatHub> chatHub) {
|
||||||
|
this._chatSettings = chatSettings.Value;
|
||||||
|
this._notificationService = notificationService;
|
||||||
|
this._chatHub = chatHub;
|
||||||
|
this._userManager = userManager;
|
||||||
|
this._subscriptionStore = subscriptionStore;
|
||||||
|
|
||||||
|
}
|
||||||
|
public async Task<bool> InitiateSupportRequest(string fromUser, ChatViewModel message) {
|
||||||
|
if (!string.IsNullOrEmpty(_chatSettings.CurrentChatUser)) {
|
||||||
|
var user = await _userManager.FindByEmailAsync(_chatSettings.CurrentChatUser);
|
||||||
|
if (!string.IsNullOrEmpty(user?.Id)) {
|
||||||
|
message.ToUserId = user.Id;
|
||||||
|
message.ToUserName = user.FullName;
|
||||||
|
//send firebase message to notify via web worker
|
||||||
|
WebPush.PushMessage pushMessage = new WebPush.PushMessage(message.Message) {
|
||||||
|
Topic = "New support chat message",
|
||||||
|
Urgency = PushMessageUrgency.Normal
|
||||||
|
};
|
||||||
|
await _subscriptionStore.ForEachSubscriptionAsync(user.Id, (WebPush.PushSubscription subscription) => {
|
||||||
|
_notificationService.SendNotificationAsync(subscription, pushMessage);
|
||||||
|
});
|
||||||
|
|
||||||
|
//send SignalR message to notify in chat.component
|
||||||
|
await _chatHub.SendUserAsync(user.Email, "SendMessage", new object[] { message });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ using Newtonsoft.Json;
|
|||||||
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Converters;
|
||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Serialization;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
using PodNoms.Api.Models.ViewModels;
|
using PodNoms.Api.Models.ViewModels;
|
||||||
using PodNoms.Api.Persistence;
|
using PodNoms.Api.Persistence;
|
||||||
using PodNoms.Api.Providers;
|
using PodNoms.Api.Providers;
|
||||||
@@ -97,9 +98,10 @@ namespace PodNoms.Api {
|
|||||||
services.AddOptions();
|
services.AddOptions();
|
||||||
services.Configure<AppSettings>(Configuration.GetSection("App"));
|
services.Configure<AppSettings>(Configuration.GetSection("App"));
|
||||||
services.Configure<StorageSettings>(Configuration.GetSection("Storage"));
|
services.Configure<StorageSettings>(Configuration.GetSection("Storage"));
|
||||||
services.Configure<ApplicationsSettings>(Configuration.GetSection("ApplicationsSettings"));
|
services.Configure<HelpersSettings>(Configuration.GetSection("HelpersSettings"));
|
||||||
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
|
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
|
||||||
services.Configure<FacebookAuthSettings>(Configuration.GetSection("FacebookAuthSettings"));
|
services.Configure<FacebookAuthSettings>(Configuration.GetSection("FacebookAuthSettings"));
|
||||||
|
services.Configure<ChatSettings>(Configuration.GetSection("ChatSettings"));
|
||||||
services.Configure<ImageFileStorageSettings>(Configuration.GetSection("ImageFileStorageSettings"));
|
services.Configure<ImageFileStorageSettings>(Configuration.GetSection("ImageFileStorageSettings"));
|
||||||
services.Configure<AudioFileStorageSettings>(Configuration.GetSection("AudioFileStorageSettings"));
|
services.Configure<AudioFileStorageSettings>(Configuration.GetSection("AudioFileStorageSettings"));
|
||||||
services.Configure<FormOptions>(options => {
|
services.Configure<FormOptions>(options => {
|
||||||
@@ -201,10 +203,24 @@ namespace PodNoms.Api {
|
|||||||
x.ValueLengthLimit = int.MaxValue;
|
x.ValueLengthLimit = int.MaxValue;
|
||||||
x.MultipartBodyLengthLimit = int.MaxValue; // In case of multipart
|
x.MultipartBodyLengthLimit = int.MaxValue; // In case of multipart
|
||||||
});
|
});
|
||||||
services.AddSignalR(config => { });
|
|
||||||
|
services.AddSignalR()
|
||||||
|
.AddJsonProtocol(options => options.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver() {
|
||||||
|
NamingStrategy = new CamelCaseNamingStrategy() {
|
||||||
|
ProcessDictionaryKeys = true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
services.AddCors(options => {
|
services.AddCors(options => {
|
||||||
options.AddPolicy("AllowAllOrigins",
|
options.AddPolicy("PodNomsClientPolicy",
|
||||||
|
builder => builder
|
||||||
|
.AllowAnyMethod()
|
||||||
|
.AllowAnyHeader()
|
||||||
|
.WithOrigins("http://localhost:4200", "https://*.podnoms.com")
|
||||||
|
.AllowCredentials());
|
||||||
|
});
|
||||||
|
services.AddCors(options => {
|
||||||
|
options.AddPolicy("AllowAllPolicy",
|
||||||
builder => builder
|
builder => builder
|
||||||
.AllowAnyOrigin()
|
.AllowAnyOrigin()
|
||||||
.AllowAnyMethod()
|
.AllowAnyMethod()
|
||||||
@@ -224,6 +240,7 @@ namespace PodNoms.Api {
|
|||||||
services.AddScoped<IUrlProcessService, UrlProcessService>();
|
services.AddScoped<IUrlProcessService, UrlProcessService>();
|
||||||
services.AddScoped<INotifyJobCompleteService, NotifyJobCompleteService>();
|
services.AddScoped<INotifyJobCompleteService, NotifyJobCompleteService>();
|
||||||
services.AddScoped<IAudioUploadProcessService, AudioUploadProcessService>();
|
services.AddScoped<IAudioUploadProcessService, AudioUploadProcessService>();
|
||||||
|
services.AddScoped<ISupportChatService, SupportChatService>();
|
||||||
services.AddScoped<IMailSender, MailgunSender>();
|
services.AddScoped<IMailSender, MailgunSender>();
|
||||||
services.AddScoped<YouTubeParser>();
|
services.AddScoped<YouTubeParser>();
|
||||||
services.AddScoped<MixcloudParser>();
|
services.AddScoped<MixcloudParser>();
|
||||||
@@ -271,7 +288,7 @@ namespace PodNoms.Api {
|
|||||||
});
|
});
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
|
|
||||||
app.UseCors("AllowAllOrigins");
|
app.UseCors("AllowAllPolicy");
|
||||||
|
|
||||||
app.UseSignalR(routes => {
|
app.UseSignalR(routes => {
|
||||||
routes.MapHub<AudioProcessingHub>("/hubs/audioprocessing");
|
routes.MapHub<AudioProcessingHub>("/hubs/audioprocessing");
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Google.Apis.Services;
|
|||||||
using Google.Apis.YouTube.v3;
|
using Google.Apis.YouTube.v3;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using PodNoms.Api.Models;
|
using PodNoms.Api.Models;
|
||||||
|
using PodNoms.Api.Models.Settings;
|
||||||
|
|
||||||
namespace PodNoms.Api.Utils.RemoteParsers {
|
namespace PodNoms.Api.Utils.RemoteParsers {
|
||||||
public partial class YouTubeParser {
|
public partial class YouTubeParser {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"Key": "9f59ab0666214980ef76",
|
"Key": "9f59ab0666214980ef76",
|
||||||
"Cluster": "eu"
|
"Cluster": "eu"
|
||||||
},
|
},
|
||||||
"ApplicationsSettings": {
|
"HelpersSettings": {
|
||||||
"Downloader": "/usr/local/bin/youtube-dl"
|
"Downloader": "/usr/local/bin/youtube-dl"
|
||||||
},
|
},
|
||||||
"ImageFileStorageSettings": {
|
"ImageFileStorageSettings": {
|
||||||
|
|||||||
Reference in New Issue
Block a user