mirror of
https://github.com/fergalmoran/podnoms.git
synced 2025-12-22 09:18:08 +00:00
Waiting for token reset
This commit is contained in:
@@ -16,7 +16,7 @@ import { ProgressbarModule } from 'ngx-bootstrap/progressbar';
|
|||||||
import { AngularFireDatabaseModule } from 'angularfire2/database';
|
import { AngularFireDatabaseModule } from 'angularfire2/database';
|
||||||
import { AngularFireAuthModule } from 'angularfire2/auth';
|
import { AngularFireAuthModule } from 'angularfire2/auth';
|
||||||
import { AngularFireModule } from 'angularfire2';
|
import { AngularFireModule } from 'angularfire2';
|
||||||
import { QuillModule } from 'ngx-quill'
|
import { QuillModule } from 'ngx-quill';
|
||||||
|
|
||||||
import { SocialLoginModule, AuthServiceConfig } from 'angularx-social-login';
|
import { SocialLoginModule, AuthServiceConfig } from 'angularx-social-login';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Component, OnInit, ReflectiveInjector } from '@angular/core';
|
import { Component, OnInit, ReflectiveInjector } from '@angular/core';
|
||||||
import { AppInsightsService } from '../../services/app-insights.service';
|
import { AppInsightsService } from '../../services/app-insights.service';
|
||||||
|
import { environment } from 'environments/environment';
|
||||||
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-base-page',
|
selector: 'app-base-page',
|
||||||
template: ''
|
template: ''
|
||||||
@@ -18,4 +19,10 @@ export class BasePageComponent {
|
|||||||
private logNavigation() {
|
private logNavigation() {
|
||||||
this._appInsightsService.logPageView();
|
this._appInsightsService.logPageView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected formatError(error: string): string {
|
||||||
|
return `${error}<br />Please visit <a href="${
|
||||||
|
environment.HELP_URL
|
||||||
|
}">here</a> and request help.`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,8 +49,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-danger" *ngIf="errorMessage" role="alert">
|
<div class="alert alert-danger" *ngIf="errorMessage" role="alert" [innerHTML]="errorMessage">
|
||||||
{{errorMessage}}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-12 new-user-alert" *ngIf="brandNew">
|
<div class="col-md-12 new-user-alert" *ngIf="brandNew">
|
||||||
<div class="alert alert-success" role="alert">
|
<div class="alert alert-success" role="alert">
|
||||||
|
|||||||
@@ -39,8 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-danger" *ngIf="errorMessage" role="alert">
|
<div class="alert alert-danger" *ngIf="errorMessage" [innerHTML]="errorMessage">
|
||||||
{{errorMessage}}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row gutters-tiny">
|
<div class="form-group row gutters-tiny">
|
||||||
<div class="col-12 mb-10">
|
<div class="col-12 mb-10">
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
<div id="page-container"
|
<div id="page-container" class="main-content-boxed">
|
||||||
class="main-content-boxed">
|
|
||||||
<main id="main-container">
|
<main id="main-container">
|
||||||
<div class="bg-image"
|
<div class="bg-image" style="background-image: url('/assets/img/robothand.jpg'); background-size: 100% 100%;">
|
||||||
style="background-image: url('/assets/img/robothand.jpg'); background-size: 100% 100%;">
|
|
||||||
<div class="hero-static content content-full bg-white">
|
<div class="hero-static content content-full bg-white">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<a class="link-effect font-w700">
|
<a class="link-effect font-w700">
|
||||||
@@ -14,45 +12,48 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-sm-8 col-md-6 col-xl-4">
|
<div class="col-sm-8 col-md-6 col-xl-4">
|
||||||
<form class="js-validation-signin"
|
<form class="js-validation-signin" action="" (ngSubmit)="resetPassword()" method="post">
|
||||||
action=""
|
<div class="form-group row" *ngIf="noToken">
|
||||||
(ngSubmit)="resetPassword()"
|
|
||||||
method="post">
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="form-material floating">
|
<div class="form-material floating">
|
||||||
<input type="text"
|
<input type="text" class="form-control" id="login-username" name="login-username" [(ngModel)]="username">
|
||||||
class="form-control"
|
|
||||||
id="login-username"
|
|
||||||
name="login-username"
|
|
||||||
[(ngModel)]="username">
|
|
||||||
<label for="login-username">Email Address</label>
|
<label for="login-username">Email Address</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-danger"
|
<div class="form-group row" *ngIf="!noToken">
|
||||||
*ngIf="errorMessage"
|
<div class="col-12">
|
||||||
role="alert">
|
<div class="form-material ">
|
||||||
{{errorMessage}}
|
<input type="password" class="form-control" id="login-password" name="login-password" [(ngModel)]="newPassword">
|
||||||
|
<label for="login-password">New password</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row gutters-tiny"
|
<div class="form-group row" *ngIf="!noToken">
|
||||||
*ngIf="successMessage">
|
<div class="col-12 ">
|
||||||
<div class="col-12 mb-10">
|
<div class="form-material ">
|
||||||
<div class="alert alert-success"
|
<input type="password " class="form-control " id="login-password2 " name="login-password2
|
||||||
role="alert">
|
" [(ngModel)]="newPasswordRepeat ">
|
||||||
|
<label for="login-password ">Repeat password</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-danger " *ngIf="errorMessage " role="alert " [innerHTML]="errorMessage ">
|
||||||
|
</div>
|
||||||
|
<div class="form-group row gutters-tiny " *ngIf="successMessage ">
|
||||||
|
<div class="col-12 mb-10 ">
|
||||||
|
<div class="alert alert-success " role="alert ">
|
||||||
<strong>Success!</strong> {{successMessage}}
|
<strong>Success!</strong> {{successMessage}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row gutters-tiny">
|
<div class="form-group row gutters-tiny ">
|
||||||
<div class="col-12 mb-10">
|
<div class="col-12 mb-10 ">
|
||||||
<a [routerLink]="['']"
|
<a [routerLink]="[ ''] " *ngIf="successMessage " class="btn btn-block btn-hero btn-noborder
|
||||||
*ngIf="successMessage"
|
btn-rounded btn-alt-secondary ">Go Home..</a>
|
||||||
class="btn btn-block btn-hero btn-noborder btn-rounded btn-alt-secondary">Go Home..</a>
|
<button type="submit " *ngIf="!successMessage " class="btn btn-block btn-hero btn-noborder
|
||||||
<button type="submit"
|
btn-rounded btn-alt-primary ">
|
||||||
*ngIf="!successMessage"
|
<i class="si si-reload mr-10 "></i> Reset Password
|
||||||
class="btn btn-block btn-hero btn-noborder btn-rounded btn-alt-primary">
|
|
||||||
<i class="si si-reload mr-10"></i> Reset Password
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Component, OnInit } from '@angular/core';
|
|||||||
import 'rxjs/add/operator/catch';
|
import 'rxjs/add/operator/catch';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { BasePageComponent } from '../base-page/base-page.component';
|
import { BasePageComponent } from '../base-page/base-page.component';
|
||||||
|
import { AppInsightsService } from '../../services/app-insights.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-reset',
|
selector: 'app-reset',
|
||||||
@@ -13,23 +14,41 @@ export class ResetComponent extends BasePageComponent implements OnInit {
|
|||||||
username: string;
|
username: string;
|
||||||
errorMessage: string;
|
errorMessage: string;
|
||||||
successMessage: string;
|
successMessage: string;
|
||||||
constructor(private _authService: PodnomsAuthService) {
|
noToken: boolean = true;
|
||||||
|
newPassword: string;
|
||||||
|
newPasswordRepeat: string;
|
||||||
|
constructor(
|
||||||
|
private _authService: PodnomsAuthService,
|
||||||
|
private _insightsService: AppInsightsService
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
resetPassword() {
|
resetPassword() {
|
||||||
if (this.username) {
|
if (this.username) {
|
||||||
this._authService.resetPassword(this.username);
|
this._authService.resetPassword(this.username).subscribe(
|
||||||
// .catch(err => {
|
(result) => {
|
||||||
// this.errorMessage = err.description;
|
if (result.status === 200) {
|
||||||
// return Observable.of(`Error resetting password: ${err.description}`);
|
console.log('reset.component.ts', 'method', result);
|
||||||
// })
|
this.errorMessage = '';
|
||||||
// .subscribe(result => {
|
this.successMessage = `A password reset link has been sent to ${
|
||||||
// console.log('reset.component.ts', 'method', result);
|
this.username
|
||||||
// this.errorMessage = '';
|
}`;
|
||||||
// this.successMessage = `A password reset link has been sent to ${this.username}`;
|
} else {
|
||||||
// });
|
this.errorMessage =
|
||||||
|
'Unable to reset your password\nPlease visit https://talk.podnoms.com and request help.';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
this.errorMessage = this.formatError(
|
||||||
|
'Unable to reset your password'
|
||||||
|
);
|
||||||
|
this._insightsService.logEvent('client_error', {
|
||||||
|
message: err.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.errorMessage = 'Please enter your email address';
|
this.errorMessage = 'Please enter your email address';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,15 @@ export class PodnomsAuthService extends BaseService {
|
|||||||
window.location.reload(true);
|
window.location.reload(true);
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
public resetPassword(userName: string) {}
|
public resetPassword(userName: string): Observable<Response> {
|
||||||
public loginSocial(provider: string): void {}
|
const body = JSON.stringify({
|
||||||
|
email: userName
|
||||||
|
});
|
||||||
|
return this._http
|
||||||
|
.post<Response>(
|
||||||
|
environment.API_HOST + '/auth/forgotpassword',
|
||||||
|
body,
|
||||||
|
this.httpOptions
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,11 @@ export const environment = {
|
|||||||
API_HOST: 'https://api.podnoms.com',
|
API_HOST: 'https://api.podnoms.com',
|
||||||
SIGNALR_HOST: 'https://rt.podnoms.com',
|
SIGNALR_HOST: 'https://rt.podnoms.com',
|
||||||
BASE_URL: 'https://podnoms.com',
|
BASE_URL: 'https://podnoms.com',
|
||||||
|
HELP_URL: 'https://talk.podnoms.com',
|
||||||
appInsights: {
|
appInsights: {
|
||||||
instrumentationKey: '020b002a-bd3d-4b25-8a74-cab16fd39dfc'
|
instrumentationKey: '020b002a-bd3d-4b25-8a74-cab16fd39dfc'
|
||||||
|
},
|
||||||
|
messaging: {
|
||||||
|
endpoint: 'https://fcm.googleapis.com/fcm/send'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export const environment = {
|
|||||||
DOMAIN: 'localhost',
|
DOMAIN: 'localhost',
|
||||||
SIGNALR_HOST: ROOT_URL,
|
SIGNALR_HOST: ROOT_URL,
|
||||||
BASE_URL: 'http://localhost:4200/',
|
BASE_URL: 'http://localhost:4200/',
|
||||||
|
HELP_URL: 'https://talk.podnoms.com',
|
||||||
appInsights: {
|
appInsights: {
|
||||||
instrumentationKey: '020b002a-bd3d-4b25-8a74-cab16fd39dfc'
|
instrumentationKey: '020b002a-bd3d-4b25-8a74-cab16fd39dfc'
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@@ -14,11 +16,14 @@ namespace PodNoms.Api.Controllers {
|
|||||||
public class AuthController : Controller {
|
public class AuthController : Controller {
|
||||||
private readonly UserManager<ApplicationUser> _userManager;
|
private readonly UserManager<ApplicationUser> _userManager;
|
||||||
private readonly IJwtFactory _jwtFactory;
|
private readonly IJwtFactory _jwtFactory;
|
||||||
|
private readonly IEmailSender _emailSender;
|
||||||
private readonly JwtIssuerOptions _jwtOptions;
|
private readonly JwtIssuerOptions _jwtOptions;
|
||||||
|
|
||||||
public AuthController(UserManager<ApplicationUser> userManager, IJwtFactory jwtFactory, IOptions<JwtIssuerOptions> jwtOptions) {
|
public AuthController(UserManager<ApplicationUser> userManager, IJwtFactory jwtFactory, IOptions<JwtIssuerOptions> jwtOptions,
|
||||||
|
IEmailSender emailSender) {
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_jwtFactory = jwtFactory;
|
_jwtFactory = jwtFactory;
|
||||||
|
_emailSender = emailSender;
|
||||||
_jwtOptions = jwtOptions.Value;
|
_jwtOptions = jwtOptions.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +39,7 @@ namespace PodNoms.Api.Controllers {
|
|||||||
return BadRequest(Errors.AddErrorToModelState("login_failure", "Invalid username or password.", ModelState));
|
return BadRequest(Errors.AddErrorToModelState("login_failure", "Invalid username or password.", ModelState));
|
||||||
}
|
}
|
||||||
|
|
||||||
var jwt = await Tokens.GenerateJwt(identity, _jwtFactory, credentials.UserName, _jwtOptions,
|
var jwt = await Tokens.GenerateJwt(identity, _jwtFactory, credentials.UserName, _jwtOptions,
|
||||||
new JsonSerializerSettings { Formatting = Formatting.Indented });
|
new JsonSerializerSettings { Formatting = Formatting.Indented });
|
||||||
return new OkObjectResult(jwt);
|
return new OkObjectResult(jwt);
|
||||||
}
|
}
|
||||||
@@ -51,12 +56,51 @@ namespace PodNoms.Api.Controllers {
|
|||||||
// check the credentials
|
// check the credentials
|
||||||
if (await _userManager.CheckPasswordAsync(userToVerify, password)) {
|
if (await _userManager.CheckPasswordAsync(userToVerify, password)) {
|
||||||
await _userManager.UpdateAsync(userToVerify);
|
await _userManager.UpdateAsync(userToVerify);
|
||||||
|
|
||||||
return await Task.FromResult(_jwtFactory.GenerateClaimsIdentity(userName, userToVerify.Id));
|
return await Task.FromResult(_jwtFactory.GenerateClaimsIdentity(userName, userToVerify.Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Credentials are invalid, or account doesn't exist
|
// Credentials are invalid, or account doesn't exist
|
||||||
return await Task.FromResult<ClaimsIdentity>(null);
|
return await Task.FromResult<ClaimsIdentity>(null);
|
||||||
}
|
}
|
||||||
|
[HttpPost("reset")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<IActionResult> ForgotPassword([FromBody]ForgotPasswordViewModel model) {
|
||||||
|
if (ModelState.IsValid) {
|
||||||
|
var user = await _userManager.FindByNameAsync(model.Email);
|
||||||
|
if (user == null) {
|
||||||
|
// Don't reveal that the user does not exist or is not confirmed
|
||||||
|
return BadRequest(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
|
||||||
|
// Send an email with this link
|
||||||
|
var code = await _userManager.GeneratePasswordResetTokenAsync(user);
|
||||||
|
var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
|
||||||
|
await _emailSender.SendEmailAsync(model.Email, "Reset Password",
|
||||||
|
"Please reset your password by clicking here: <a href=\"" + callbackUrl + "\">link</a>");
|
||||||
|
return Ok(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got this far, something failed, redisplay form
|
||||||
|
return BadRequest(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("/reset")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model) {
|
||||||
|
if (!ModelState.IsValid) {
|
||||||
|
return BadRequest("Unable to reset your password at this time");
|
||||||
|
}
|
||||||
|
var user = await _userManager.FindByNameAsync(model.Email);
|
||||||
|
if (user == null) {
|
||||||
|
return BadRequest("Unable to reset your password at this time");
|
||||||
|
}
|
||||||
|
var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);
|
||||||
|
if (result.Succeeded) {
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
9
server/Models/ViewModels/ForgotPasswordViewModel.cs
Normal file
9
server/Models/ViewModels/ForgotPasswordViewModel.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Models.ViewModels {
|
||||||
|
public class ForgotPasswordViewModel {
|
||||||
|
[Required]
|
||||||
|
[EmailAddress]
|
||||||
|
public string Email { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
21
server/Models/ViewModels/ResetPasswordViewModel.cs
Normal file
21
server/Models/ViewModels/ResetPasswordViewModel.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Models.ViewModels {
|
||||||
|
public class ResetPasswordViewModel {
|
||||||
|
[Required]
|
||||||
|
[EmailAddress]
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Display(Name = "Confirm password")]
|
||||||
|
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
|
||||||
|
public string ConfirmPassword { get; set; }
|
||||||
|
|
||||||
|
public string Code { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
17
server/Services/Auth/EmailSender.cs
Normal file
17
server/Services/Auth/EmailSender.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
|
using PodNoms.Api.Services;
|
||||||
|
|
||||||
|
namespace PodNoms.Api.Services.Auth {
|
||||||
|
public class EmailSender : IEmailSender {
|
||||||
|
private readonly IMailSender _mailSender;
|
||||||
|
|
||||||
|
public EmailSender(IMailSender mailSender) {
|
||||||
|
this._mailSender = mailSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SendEmailAsync(string email, string subject, string htmlMessage) {
|
||||||
|
await this._mailSender.SendEmail(email, subject, htmlMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,10 +20,10 @@ namespace PodNoms.Api.Services {
|
|||||||
|
|
||||||
public async Task<bool> SendEmail(string email, string subject, string message){
|
public async Task<bool> SendEmail(string email, string subject, string message){
|
||||||
using (var client = new HttpClient { BaseAddress = new Uri(_emailSettings.ApiBaseUri) }) {
|
using (var client = new HttpClient { BaseAddress = new Uri(_emailSettings.ApiBaseUri) }) {
|
||||||
client.DefaultRequestHeaders.Authorization =
|
client.DefaultRequestHeaders.Authorization =
|
||||||
new AuthenticationHeaderValue("Basic",
|
new AuthenticationHeaderValue("Basic",
|
||||||
Convert.ToBase64String(Encoding.ASCII.GetBytes(_emailSettings.ApiKey)));
|
Convert.ToBase64String(Encoding.ASCII.GetBytes(_emailSettings.ApiKey)));
|
||||||
|
|
||||||
_logger.LogInformation($"From: {_emailSettings.From}\nTo: {email}\nApi key: {_emailSettings.ApiKey}");
|
_logger.LogInformation($"From: {_emailSettings.From}\nTo: {email}\nApi key: {_emailSettings.ApiKey}");
|
||||||
|
|
||||||
var content = new FormUrlEncodedContent(new[]
|
var content = new FormUrlEncodedContent(new[]
|
||||||
@@ -37,7 +37,7 @@ namespace PodNoms.Api.Services {
|
|||||||
var result = await client.PostAsync(_emailSettings.RequestUri, content).ConfigureAwait(false);
|
var result = await client.PostAsync(_emailSettings.RequestUri, content).ConfigureAwait(false);
|
||||||
if (result.StatusCode == HttpStatusCode.OK)
|
if (result.StatusCode == HttpStatusCode.OK)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
_logger.LogError($"Error {result.StatusCode} sending mail\n{result.ReasonPhrase}");
|
_logger.LogError($"Error {result.StatusCode} sending mail\n{result.ReasonPhrase}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ using Microsoft.AspNetCore.HttpOverrides;
|
|||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
|
|
||||||
namespace PodNoms.Api {
|
namespace PodNoms.Api {
|
||||||
public class Startup {
|
public class Startup {
|
||||||
@@ -218,6 +219,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<IEmailSender, PodNoms.Api.Services.Auth.EmailSender>();
|
||||||
services.AddScoped<IMailSender, MailgunSender>();
|
services.AddScoped<IMailSender, MailgunSender>();
|
||||||
services.AddHttpClient<Services.Gravatar.GravatarHttpClient>();
|
services.AddHttpClient<Services.Gravatar.GravatarHttpClient>();
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
},
|
},
|
||||||
"App": {
|
"App": {
|
||||||
"Version": "0.22.0",
|
"Version": "0.22.0",
|
||||||
|
"SiteUrl": "http://localhost:4200",
|
||||||
"RssUrl": "http://localhost:5000/rss/"
|
"RssUrl": "http://localhost:5000/rss/"
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
|
|||||||
Reference in New Issue
Block a user