master #475

Closed
edraft wants to merge 60 commits from master into dev
9 changed files with 77 additions and 43 deletions
Showing only changes of commit 60d81ce18b - Show all commits

View File

@ -2,22 +2,22 @@
"api": {
"api": {
"test_mail": {
"message": "Dies ist eine Test-Mail vom Kruemelmonster Web Interface\r\nGesendet von {}-{}",
"message": "Dies ist eine Test-Mail vom Krümelmonster Web Interface\r\nGesendet von {}-{}",
"subject": "Krümelmonster Web Interface Test-Mail"
}
},
"auth": {
"confirmation": {
"message": "Öffne den Link, um die E-Mail zu bestätigen:\n{}auth/register/{}",
"message": "Öffne den Link, um die E-Mail zu bestätigen:\r\n{}auth/register/{}",
"subject": "E-Mail für {} {} bestätigen"
},
"forgot_password": {
"message": "Öffne den Link, um das Passwort zu ändern:\n{}auth/forgot-password/{}",
"message": "Öffne den Link, um das Passwort zu ändern:\r\n{}auth/forgot-password/{}",
"subject": "Passwort für {} {} zurücksetzen"
}
},
"mail": {
"automatic_mail": "\n\nDies ist eine automatische E-Mail.\nGesendet von {}-{}@{}"
"automatic_mail": "\r\n\r\nDies ist eine automatische E-Mail.\r\nGesendet von {}-{}@{}"
}
},
"common": {

View File

@ -114,3 +114,7 @@ class AuthServiceABC(ABC):
@abstractmethod
async def reset_password_async(self, rp_dto: ResetPasswordDTO):
pass
@abstractmethod
async def resend_confirmation_email_by_mail(self, mail: str):
pass

View File

@ -84,6 +84,11 @@ class AuthController:
self._auth_service.add_auth_user(dto)
return "", 200
@Route.post(f"{BasePath}/resend-confirmation-email-by-mail/<mail>")
async def resend_confirmation_email_by_user_id(self, mail: str):
await self._auth_service.resend_confirmation_email_by_mail(mail)
return "", 200
@Route.post(f"{BasePath}/register-by-id/<id>")
async def register_id(self, id: str):
result = await self._auth_service.confirm_email_async(id)

View File

@ -16,6 +16,7 @@ from bot_api.api import Api
from bot_api.configuration.discord_authentication_settings import (
DiscordAuthenticationSettings,
)
from bot_api.exception.service_exception import ServiceException
from bot_api.logging.api_logger import ApiLogger
from bot_api.model.auth_user_dto import AuthUserDTO
from bot_api.route.route import Route
@ -90,5 +91,10 @@ class AuthDiscordController:
AuthRoleEnum.normal,
)
result = await self._auth_service.login_discord_async(dto, response["id"])
return jsonify(result.to_dict())
try:
result = await self._auth_service.login_discord_async(dto, response["id"])
return jsonify(result.to_dict())
except ServiceException as e:
r = jsonify({"email": dto.email})
r.status_code = 403
return r

View File

@ -1,6 +1,5 @@
import hashlib
import re
import textwrap
import uuid
from datetime import datetime, timedelta, timezone
from threading import Thread
@ -172,11 +171,7 @@ class AuthService(AuthServiceABC):
mail.add_header("Content-Transfer-Encoding: quoted-printable")
mail.add_receiver(str(email))
mail.subject = subject
mail.body = textwrap.dedent(
f"""{message}
{self._t.transform('api.mail.automatic_mail').format(self._environment.application_name, self._environment.environment_name, self._environment.host_name)}
"""
)
mail.body = f"{message}\r\n{self._t.transform('api.mail.automatic_mail').format(self._environment.application_name, self._environment.environment_name, self._environment.host_name)}"
thr = Thread(target=self._mailer.send_mail, args=[mail])
thr.start()
@ -599,3 +594,12 @@ class AuthService(AuthServiceABC):
user.forgot_password_id = None
self._auth_users.update_auth_user(user)
self._db.save_changes()
async def resend_confirmation_email_by_mail(self, mail: str):
user = self._auth_users.find_auth_user_by_email(mail)
if user is None:
raise ServiceException(ServiceErrorCode.InvalidUser, f"User not found")
if user.confirmation_id is None:
raise ServiceException(ServiceErrorCode.DataAlreadyExists, f"User already confirmed")
self._send_confirmation_id_to_user(user)

View File

@ -69,6 +69,17 @@ export class LoginComponent implements OnInit {
this.spinnerService.hideSpinner();
}
openConfirmationMailInfo(email: string) {
this.confirmDialog.confirmDialog(
this.translate.instant(
"auth.login.message.confirm_email"),
this.translate.instant(
"auth.login.message.confirm_email_d",
{ email: email }
)
);
}
checkDiscordLogin() {
this.route.queryParams.pipe(catchError(err => {
this.spinnerService.hideSpinner();
@ -87,19 +98,31 @@ export class LoginComponent implements OnInit {
this.spinnerService.hideSpinner();
this.router.navigate(["auth", "login"]).then(() => {
});
this.state = "";
this.code = "";
this.confirmDialog.confirmDialog(
this.translate.instant(
"auth.login.message.confirm_email"),
this.translate.instant(
"auth.login.message.confirm_email_resend"
),
() => {
this.authService.resendConfirmationMailByMail(err.error.email).subscribe(mail => {
this.openConfirmationMailInfo(err.error.email);
}
);
this.state = "";
this.code = "";
},
() => {
this.state = "";
this.code = "";
}
);
return throwError(() => err);
})).subscribe(token => {
if (token.firstLogin) {
this.confirmDialog.confirmDialog(
this.translate.instant(
"auth.login.message.confirm_email"),
this.translate.instant(
"auth.login.message.confirm_email_d",
{ email: this.authService.getEMailFromDecodedToken(this.authService.getDecodedToken(token)) }
)
);
this.openConfirmationMailInfo(this.authService.getEMailFromDecodedToken(this.authService.getDecodedToken(token)) ?? "");
}
this.authService.saveToken(token);

View File

@ -2,7 +2,7 @@ import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Router } from "@angular/router";
import { JwtHelperService } from "@auth0/angular-jwt";
import { BehaviorSubject, firstValueFrom, Observable, Subject, Subscription, throwError } from "rxjs";
import { BehaviorSubject, firstValueFrom, Observable, Subscription, throwError } from "rxjs";
import { catchError } from "rxjs/operators";
import { AdminUpdateUserDTO } from "src/app/models/auth/admin-update-user.dto";
import { AuthRoles } from "src/app/models/auth/auth-roles.enum";
@ -16,7 +16,6 @@ import { GetFilteredAuthUsersResultDTO } from "src/app/models/selection/auth-use
import { SettingsService } from "../settings/settings.service";
import { SpinnerService } from "../spinner/spinner.service";
import { DiscordAuthURL } from "../../models/auth/discord-auth-url.dto";
import { OAuthDTO } from "../../models/auth/oauth.dto";
@Injectable({
providedIn: "root"
@ -108,6 +107,14 @@ export class AuthService {
});
}
resendConfirmationMailByMail(email: string): Observable<unknown> {
return this.http.post(`${this.appsettings.getApiURL()}/api/auth/resend-confirmation-email-by-mail/${email}`, {
headers: new HttpHeaders({
"Content-Type": "application/json"
})
});
}
getEMailFromforgotPasswordId(id: string): Observable<EMailStringDTO> {
return this.http.post<EMailStringDTO>(`${this.appsettings.getApiURL()}/api/auth/confirm-forgot-password/${id}`, {
headers: new HttpHeaders({
@ -173,23 +180,6 @@ export class AuthService {
});
}
// /api/auth/discord/register?code=
discordRegister(oAuthDTO: OAuthDTO) {
return this.http.post(`${this.appsettings.getApiURL()}/api/auth/discord/register`, oAuthDTO, {
headers: new HttpHeaders({
"Content-Type": "application/json"
})
});
}
// discordGetUser(code: string, state: string) {
// return this.http.get<AuthUserDTO>(`${this.appsettings.getApiURL()}/api/auth/discord/get-user?code=${code}&state=${state}`, {
// headers: new HttpHeaders({
// 'Content-Type': 'application/json'
// })
// });
// }
/* utils */
saveToken(token: TokenDTO): void {
localStorage.setItem("jwt", token.token);

View File

@ -93,7 +93,8 @@
"login_with_discord": "Mit Discord einloggen",
"message": {
"confirm_email": "E-Mail Bestätigen",
"confirm_email_d": "Sie müssen die E-Mail {{email}} Bestätigen, in dem Sie den Link öffnen, welchen wir Ihnen zugesendet haben."
"confirm_email_d": "Sie müssen die E-Mail {{email}} Bestätigen, in dem Sie den Link öffnen, welchen wir Ihnen zugesendet haben.",
"confirm_email_resend": "Sollen wir die Bestätigungsmail neu verschicken?"
},
"password": "Passwort",
"password_required": "Passwort benötigt",

View File

@ -93,7 +93,8 @@
"login_with_discord": "Login with discord",
"message": {
"confirm_email": "Confirm E-Mail",
"confirm_email_d": "You have to confirm your email {{email}} Please confirm your account through the link in the email."
"confirm_email_d": "You have to confirm your email {{email}} Please confirm your account through the link in the email.",
"confirm_email_resend": "Should we resend the confirmation email?"
},
"password": "Password",
"password_required": "Passwort required",