Skip to content

Commit

Permalink
Request password reset from user settings
Browse files Browse the repository at this point in the history
  • Loading branch information
duncte123 committed Feb 24, 2024
1 parent 1606b64 commit 8075caf
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 6 deletions.
11 changes: 9 additions & 2 deletions src/app/auth/password-reset/password-reset.component.html
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
<section class="section container">
<h1 class="title">Reset your password!</h1>

<div class="notification is-danger" *ngIf="errorTranslationKey">
<div class="notification" [class]="notificationClass" *ngIf="errorTranslationKey">
<button class="delete" (click)="errorTranslationKey = null"></button>
{{ errorTranslationKey | translate }}
</div>

<div class="columns">
<div class="column is-three-fifths is-offset-one-fifth">
<form>
<fieldset [disabled]="loading">
<fieldset [disabled]="loading && resetToken">

<app-element-password-input [(password)]="newPassword"></app-element-password-input>

<div class="control">
<button type="submit" style="margin-right: 1rem"
[ngClass]="{'is-loading': loading}"
(click)="performReset()"
class="button is-primary">{{'auth.passwordReset.submit' | translate}}</button>
</div>

</fieldset>
</form>
</div>
Expand Down
50 changes: 47 additions & 3 deletions src/app/auth/password-reset/password-reset.component.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,63 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AuthService } from '../../../services/auth.service';
import { firstValueFrom } from 'rxjs';

@Component({
selector: 'app-password-reset',
templateUrl: './password-reset.component.html',
styleUrls: ['./password-reset.component.scss']
})
export class PasswordResetComponent implements OnInit {
errorTranslationKey: string | null = 'auth.passwordReset.bla';
errorTranslationKey: string | null = 'auth.passwordReset.error.PASSWORD_RESET_CODE_INVALID';
resetToken: string | null = null;

loading = false;
loading = true;
newPassword = '';
notificationClass = 'is-danger';

constructor() { }
constructor(
private authService: AuthService,
private route: ActivatedRoute,
) { }

ngOnInit(): void {
this.route.params.subscribe(params => {
this.resetToken = params['token'];

if (this.resetToken) {
this.errorTranslationKey = null;
}

this.loading = false;
});
}

async performReset() {
if (!this.resetToken) {
this.errorTranslationKey = 'auth.passwordReset.error.PASSWORD_RESET_CODE_INVALID';
}

this.loading = true;
this.notificationClass = 'is-danger';

try {
const { status } = await firstValueFrom(this.authService.resetPassword(this.resetToken, this.newPassword));

if (status === 'PASSWORD_RESET_SUCCESS') {
this.notificationClass = 'is-success';
this.errorTranslationKey = 'auth.passwordReset.success';
this.newPassword = '';
}
} catch (e: any) {
if ((e.error || {}).errors) {
this.errorTranslationKey = e.error.errors.flatMap(error => error.defaultMessage.split(',')).join('\n');
} else if (e.error.status) {
this.errorTranslationKey = `auth.passwordReset.error.${e.error.status.toUpperCase()}`;
}
} finally {
this.loading = false;
}
}

}
6 changes: 5 additions & 1 deletion src/app/user/settings/settings.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,11 @@ <h4 class="title is-4">{{'user.settings.general' | translate}}</h4>
<div class="field">
<label for="change-password" class="label">Change password</label>
<div class="control">
<button type="button" class="button is-warning" id="change-password">Reset password</button>
<button type="button"
(click)="requestNewPassword()"
class="button is-warning"
[disabled]="pwResetButtonDisabled"
id="change-password">Reset password</button>
</div>
<p class="help">Clicking this button will send you an email to reset your password, if you did not have a password set previously this will set it.</p>
</div>
Expand Down
32 changes: 32 additions & 0 deletions src/app/user/settings/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { PatreonStatusDto, RelationShip } from '../../../model/annoying-patreon-
import DOMPurify from 'dompurify';
import { AuthService } from '../../../services/auth.service';
import { InitMFADto } from '../../../model/auth';
import { firstValueFrom } from 'rxjs';

interface LangType {
value: string;
Expand All @@ -36,6 +37,7 @@ export class SettingsComponent implements OnInit {
public deactivateConfirm = false;
public deleteConfirm = false;
public deleteUsername: string;
pwResetButtonDisabled = false;

constructor(private userService: UserService,
private authService: AuthService,
Expand Down Expand Up @@ -209,6 +211,36 @@ export class SettingsComponent implements OnInit {
});
}

async requestNewPassword(): Promise<void> {
if (!this.user.emailVerified) {
this.translateService.get('auth.emailVerificationRequired').subscribe((res: string) => {
alert(res);
});

return;
}

this.loading = true;

try {
const { status } = await firstValueFrom(this.authService.requestPasswordReset(this.user.mail));

if (status === 'PASSWORD_RESET_SENT') {
this.pwResetButtonDisabled = true;
this.translateService.get('auth.passwordReset.requested').subscribe((res: string) => {
this.showSuccessToast(res);
});
}

console.log(status);
} catch (e: any) {
console.log(e.error);
alert(`Something went wrong: ${JSON.stringify(e.error)}`);
} finally {
this.loading = false;
}
}

handleMfaResult(result: boolean): void {
// true == mfa stored
// false == mfa failed
Expand Down
7 changes: 7 additions & 0 deletions src/services/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ export class AuthService extends BaseService {
return this.http.post<{ status: string }>(this.v2Url('password-reset/request'), { email });
}

resetPassword(token: String, newPassword: String) {
return this.http.post<{ status: string }>(this.v2Url('password-reset'), {
token,
password: newPassword,
});
}

initMfaSettings(): Observable<InitMFADto> {
return this.http.put<InitMFADto>(this.v2Url('mfa/init'), null);
}
Expand Down

0 comments on commit 8075caf

Please sign in to comment.