feature/refactor-login #19
|
@ -22,7 +22,7 @@ export class ClearExpiredSessionsCron {
|
|||
this.logger.log('-------------------------------------------');
|
||||
}
|
||||
|
||||
@Cron(CronExpression.EVERY_10_MINUTES, {
|
||||
@Cron(CronExpression.EVERY_5_MINUTES, {
|
||||
name: 'Clear-Expired-Tokens',
|
||||
timeZone: 'Europe/Berlin',
|
||||
})
|
||||
|
|
|
@ -34,6 +34,11 @@ export class LocalStrategy extends PassportStrategy(Strategy) {
|
|||
request.headers['user-agent']
|
||||
);
|
||||
|
||||
this.emailVerificationService.removeEmailVerificationByTokenAndEmail(
|
||||
token as string,
|
||||
email as string
|
||||
);
|
||||
|
||||
if (!verificationResult.success) {
|
||||
throw new UnauthorizedException('Invalid or expired token');
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ export class EmailVerificationService {
|
|||
): Promise<string> {
|
||||
try {
|
||||
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(
|
||||
verificationToken,
|
||||
|
@ -73,11 +73,6 @@ export class EmailVerificationService {
|
|||
throw new TokenExpiredException();
|
||||
}
|
||||
|
||||
await this.emailVerifyRepository.removeEmailVerificationByTokenAndEmail(
|
||||
tokenToVerify,
|
||||
emailToVerify
|
||||
);
|
||||
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
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> {
|
||||
await this.emailVerifyRepository.deleteAllExpiredTokens();
|
||||
}
|
||||
|
|
|
@ -457,7 +457,12 @@
|
|||
|
||||
<div
|
||||
class="modal modal-open"
|
||||
*ngIf="isTokenVerified() || isVerifying() || verificationError()"
|
||||
*ngIf="
|
||||
isTokenVerified() ||
|
||||
isVerifying() ||
|
||||
verificationError() ||
|
||||
isAutoLoginInProgress()
|
||||
"
|
||||
tabindex="-1"
|
||||
aria-labelledby="verify-modal-title"
|
||||
aria-describedby="verify-modal-description"
|
||||
|
@ -469,14 +474,20 @@
|
|||
<div class="relative w-10 h-10">
|
||||
<div
|
||||
class="absolute inset-0 transition-opacity duration-300 ease-in-out"
|
||||
[class.opacity-100]="isVerifying() && !verificationError()"
|
||||
[class.opacity-0]="!isVerifying() || verificationError()">
|
||||
[class.opacity-100]="isVerifying() || isAutoLoginInProgress()"
|
||||
[class.opacity-0]="!isVerifying() && !isAutoLoginInProgress()">
|
||||
<span class="loading loading-spinner loading-lg"></span>
|
||||
</div>
|
||||
<div
|
||||
class="absolute inset-0 transition-opacity duration-300 ease-in-out"
|
||||
[class.opacity-0]="!isTokenVerified() || verificationError()"
|
||||
[class.opacity-100]="isTokenVerified() && !verificationError()">
|
||||
[class.opacity-0]="
|
||||
!isTokenVerified() || verificationError() || isAutoLoginInProgress()
|
||||
"
|
||||
[class.opacity-100]="
|
||||
isTokenVerified() &&
|
||||
!verificationError() &&
|
||||
!isAutoLoginInProgress()
|
||||
">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-10 w-10 text-success"
|
||||
|
@ -510,8 +521,10 @@
|
|||
</div>
|
||||
<h2 id="verify-modal-title" class="text-3xl font-semibold mb-2">
|
||||
{{
|
||||
isTokenVerified() && !verificationError()
|
||||
isTokenVerified() && !verificationError() && !isAutoLoginInProgress()
|
||||
? 'Verification Complete'
|
||||
: isAutoLoginInProgress()
|
||||
? 'Logging You In'
|
||||
: verificationError()
|
||||
? 'Verification Failed'
|
||||
: 'Verifying Your Account'
|
||||
|
@ -519,8 +532,10 @@
|
|||
</h2>
|
||||
<p id="verify-modal-description">
|
||||
{{
|
||||
isTokenVerified() && !verificationError()
|
||||
isTokenVerified() && !verificationError() && !isAutoLoginInProgress()
|
||||
? 'Your email has been successfully verified.'
|
||||
: isAutoLoginInProgress()
|
||||
? 'Please wait while we automatically log you in.'
|
||||
: verificationError()
|
||||
? verificationError()
|
||||
: 'Please wait while we verify your email and token.'
|
||||
|
|
|
@ -333,12 +333,16 @@ export class WelcomeRootComponent implements OnInit {
|
|||
this.displaySkeleton.set(false);
|
||||
this.isTokenVerified.set(true);
|
||||
if (!isSignup) {
|
||||
this.isAutoLoginInProgress.set(true);
|
||||
timer(2000).subscribe(() => {
|
||||
this.authService
|
||||
.signinMagicLink({ email, token })
|
||||
.subscribe((response: SigninResponseDtoApiModel) => {
|
||||
if (response) {
|
||||
this.router.navigate(['/dashboard']);
|
||||
} else {
|
||||
this.isAutoLoginInProgress.set(false);
|
||||
// Handle login failure
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -23,7 +23,7 @@ export class ThemeService {
|
|||
}
|
||||
|
||||
public toggleTheme(): void {
|
||||
this.currentTheme = this.currentTheme === 'light' ? 'dark' : 'light';
|
||||
this.currentTheme = this.currentTheme === 'light' ? 'sunset' : 'light';
|
||||
this.setTheme(this.currentTheme);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ module.exports = {
|
|||
},
|
||||
plugins: [require('daisyui'), require('tailwindcss-animated')],
|
||||
daisyui: {
|
||||
themes: ["light", "dark"],
|
||||
darkMode: ['class', '[data-theme="dark"]']
|
||||
themes: ["light", "sunset"],
|
||||
darkMode: ['class', '[data-theme="sunset"]'],
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue