feature/refactor-login #19

Merged
igorpropisnov merged 26 commits from feature/refactor-login into main 2024-09-19 13:58:12 +02:00
7 changed files with 52 additions and 23 deletions
Showing only changes of commit 53311438ae - Show all commits

View File

@ -22,7 +22,7 @@ export class ClearExpiredSessionsCron {
this.logger.log('-------------------------------------------'); this.logger.log('-------------------------------------------');
} }
@Cron(CronExpression.EVERY_10_MINUTES, { @Cron(CronExpression.EVERY_5_MINUTES, {
name: 'Clear-Expired-Tokens', name: 'Clear-Expired-Tokens',
timeZone: 'Europe/Berlin', timeZone: 'Europe/Berlin',
}) })

View File

@ -34,6 +34,11 @@ export class LocalStrategy extends PassportStrategy(Strategy) {
request.headers['user-agent'] request.headers['user-agent']
); );
this.emailVerificationService.removeEmailVerificationByTokenAndEmail(
token as string,
email as string
);
if (!verificationResult.success) { if (!verificationResult.success) {
throw new UnauthorizedException('Invalid or expired token'); throw new UnauthorizedException('Invalid or expired token');
} }

View File

@ -23,7 +23,7 @@ export class EmailVerificationService {
): Promise<string> { ): Promise<string> {
try { try {
const verificationToken = await this.createVerificationToken(); const verificationToken = await this.createVerificationToken();
const expiresAt = new Date(Date.now() + 10 * 60 * 1000); const expiresAt = new Date(Date.now() + 5 * 60 * 1000);
await this.emailVerifyRepository.createEmailVerification( await this.emailVerifyRepository.createEmailVerification(
verificationToken, verificationToken,
@ -73,11 +73,6 @@ export class EmailVerificationService {
throw new TokenExpiredException(); throw new TokenExpiredException();
} }
await this.emailVerifyRepository.removeEmailVerificationByTokenAndEmail(
tokenToVerify,
emailToVerify
);
return { success: true }; return { success: true };
} catch (error) { } catch (error) {
if (error instanceof TokenExpiredException) { if (error instanceof TokenExpiredException) {
@ -92,6 +87,16 @@ export class EmailVerificationService {
} }
} }
public async removeEmailVerificationByTokenAndEmail(
token: string,
email: string
): Promise<void> {
await this.emailVerifyRepository.removeEmailVerificationByTokenAndEmail(
token,
email
);
}
public async deleteAllExpiredTokens(): Promise<void> { public async deleteAllExpiredTokens(): Promise<void> {
await this.emailVerifyRepository.deleteAllExpiredTokens(); await this.emailVerifyRepository.deleteAllExpiredTokens();
} }

View File

@ -457,7 +457,12 @@
<div <div
class="modal modal-open" class="modal modal-open"
*ngIf="isTokenVerified() || isVerifying() || verificationError()" *ngIf="
isTokenVerified() ||
isVerifying() ||
verificationError() ||
isAutoLoginInProgress()
"
tabindex="-1" tabindex="-1"
aria-labelledby="verify-modal-title" aria-labelledby="verify-modal-title"
aria-describedby="verify-modal-description" aria-describedby="verify-modal-description"
@ -469,14 +474,20 @@
<div class="relative w-10 h-10"> <div class="relative w-10 h-10">
<div <div
class="absolute inset-0 transition-opacity duration-300 ease-in-out" class="absolute inset-0 transition-opacity duration-300 ease-in-out"
[class.opacity-100]="isVerifying() && !verificationError()" [class.opacity-100]="isVerifying() || isAutoLoginInProgress()"
[class.opacity-0]="!isVerifying() || verificationError()"> [class.opacity-0]="!isVerifying() && !isAutoLoginInProgress()">
<span class="loading loading-spinner loading-lg"></span> <span class="loading loading-spinner loading-lg"></span>
</div> </div>
<div <div
class="absolute inset-0 transition-opacity duration-300 ease-in-out" class="absolute inset-0 transition-opacity duration-300 ease-in-out"
[class.opacity-0]="!isTokenVerified() || verificationError()" [class.opacity-0]="
[class.opacity-100]="isTokenVerified() && !verificationError()"> !isTokenVerified() || verificationError() || isAutoLoginInProgress()
"
[class.opacity-100]="
isTokenVerified() &&
!verificationError() &&
!isAutoLoginInProgress()
">
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class="h-10 w-10 text-success" class="h-10 w-10 text-success"
@ -510,20 +521,24 @@
</div> </div>
<h2 id="verify-modal-title" class="text-3xl font-semibold mb-2"> <h2 id="verify-modal-title" class="text-3xl font-semibold mb-2">
{{ {{
isTokenVerified() && !verificationError() isTokenVerified() && !verificationError() && !isAutoLoginInProgress()
? 'Verification Complete' ? 'Verification Complete'
: verificationError() : isAutoLoginInProgress()
? 'Verification Failed' ? 'Logging You In'
: 'Verifying Your Account' : verificationError()
? 'Verification Failed'
: 'Verifying Your Account'
}} }}
</h2> </h2>
<p id="verify-modal-description"> <p id="verify-modal-description">
{{ {{
isTokenVerified() && !verificationError() isTokenVerified() && !verificationError() && !isAutoLoginInProgress()
? 'Your email has been successfully verified.' ? 'Your email has been successfully verified.'
: verificationError() : isAutoLoginInProgress()
? verificationError() ? 'Please wait while we automatically log you in.'
: 'Please wait while we verify your email and token.' : verificationError()
? verificationError()
: 'Please wait while we verify your email and token.'
}} }}
</p> </p>
@if (errorReasons().length > 0) { @if (errorReasons().length > 0) {

View File

@ -333,12 +333,16 @@ export class WelcomeRootComponent implements OnInit {
this.displaySkeleton.set(false); this.displaySkeleton.set(false);
this.isTokenVerified.set(true); this.isTokenVerified.set(true);
if (!isSignup) { if (!isSignup) {
this.isAutoLoginInProgress.set(true);
timer(2000).subscribe(() => { timer(2000).subscribe(() => {
this.authService this.authService
.signinMagicLink({ email, token }) .signinMagicLink({ email, token })
.subscribe((response: SigninResponseDtoApiModel) => { .subscribe((response: SigninResponseDtoApiModel) => {
if (response) { if (response) {
this.router.navigate(['/dashboard']); this.router.navigate(['/dashboard']);
} else {
this.isAutoLoginInProgress.set(false);
// Handle login failure
} }
}); });
}); });

View File

@ -23,7 +23,7 @@ export class ThemeService {
} }
public toggleTheme(): void { public toggleTheme(): void {
this.currentTheme = this.currentTheme === 'light' ? 'dark' : 'light'; this.currentTheme = this.currentTheme === 'light' ? 'sunset' : 'light';
this.setTheme(this.currentTheme); this.setTheme(this.currentTheme);
} }

View File

@ -8,8 +8,8 @@ module.exports = {
}, },
plugins: [require('daisyui'), require('tailwindcss-animated')], plugins: [require('daisyui'), require('tailwindcss-animated')],
daisyui: { daisyui: {
themes: ["light", "dark"], themes: ["light", "sunset"],
darkMode: ['class', '[data-theme="dark"]'] darkMode: ['class', '[data-theme="sunset"]'],
} }
} }