Fixed a bug where initial registration was still telling user email was required, when it wasn't.

This commit is contained in:
Joseph Milazzo 2025-04-11 06:41:23 -05:00
parent 6b7462a790
commit ccee474b90
5 changed files with 58 additions and 35 deletions

View file

@ -138,6 +138,12 @@ public class AccountController : BaseApiController
return BadRequest(usernameValidation); return BadRequest(usernameValidation);
} }
// If Email is empty, default to the username
if (string.IsNullOrEmpty(registerDto.Email))
{
registerDto.Email = registerDto.Username;
}
var user = new AppUserBuilder(registerDto.Username, registerDto.Email, var user = new AppUserBuilder(registerDto.Username, registerDto.Email,
await _unitOfWork.SiteThemeRepository.GetDefaultTheme()).Build(); await _unitOfWork.SiteThemeRepository.GetDefaultTheme()).Build();

View file

@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace API.DTOs; namespace API.DTOs;
#nullable enable
public class RegisterDto public class RegisterDto
{ {
@ -9,7 +10,7 @@ public class RegisterDto
/// <summary> /// <summary>
/// An email to register with. Optional. Provides Forgot Password functionality /// An email to register with. Optional. Provides Forgot Password functionality
/// </summary> /// </summary>
public string Email { get; init; } = default!; public string? Email { get; set; } = default!;
[Required] [Required]
[StringLength(256, MinimumLength = 6)] [StringLength(256, MinimumLength = 6)]
public string Password { get; set; } = default!; public string Password { get; set; } = default!;

View file

@ -541,6 +541,7 @@
"version": "19.2.5", "version": "19.2.5",
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.2.5.tgz", "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.2.5.tgz",
"integrity": "sha512-b2cG41r6lilApXLlvja1Ra2D00dM3BxmQhoElKC1tOnpD6S3/krlH1DOnBB2I55RBn9iv4zdmPz1l8zPUSh7DQ==", "integrity": "sha512-b2cG41r6lilApXLlvja1Ra2D00dM3BxmQhoElKC1tOnpD6S3/krlH1DOnBB2I55RBn9iv4zdmPz1l8zPUSh7DQ==",
"dev": true,
"dependencies": { "dependencies": {
"@babel/core": "7.26.9", "@babel/core": "7.26.9",
"@jridgewell/sourcemap-codec": "^1.4.14", "@jridgewell/sourcemap-codec": "^1.4.14",
@ -568,6 +569,7 @@
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz",
"integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==",
"dev": true,
"dependencies": { "dependencies": {
"readdirp": "^4.0.1" "readdirp": "^4.0.1"
}, },
@ -582,6 +584,7 @@
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz",
"integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==",
"dev": true,
"engines": { "engines": {
"node": ">= 14.16.0" "node": ">= 14.16.0"
}, },
@ -4903,7 +4906,8 @@
"node_modules/convert-source-map": { "node_modules/convert-source-map": {
"version": "1.9.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true
}, },
"node_modules/cosmiconfig": { "node_modules/cosmiconfig": {
"version": "8.3.6", "version": "8.3.6",
@ -5350,6 +5354,7 @@
"version": "0.1.13", "version": "0.1.13",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
"dev": true,
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"iconv-lite": "^0.6.2" "iconv-lite": "^0.6.2"
@ -5359,6 +5364,7 @@
"version": "0.6.3", "version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dev": true,
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0" "safer-buffer": ">= 2.1.2 < 3.0.0"
@ -8175,7 +8181,8 @@
"node_modules/reflect-metadata": { "node_modules/reflect-metadata": {
"version": "0.2.2", "version": "0.2.2",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
"integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==" "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
"dev": true
}, },
"node_modules/replace-in-file": { "node_modules/replace-in-file": {
"version": "7.1.0", "version": "7.1.0",
@ -8396,7 +8403,7 @@
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"devOptional": true "dev": true
}, },
"node_modules/sass": { "node_modules/sass": {
"version": "1.85.0", "version": "1.85.0",
@ -8461,6 +8468,7 @@
"version": "7.7.1", "version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
"dev": true,
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "bin/semver.js"
}, },
@ -9085,6 +9093,7 @@
"version": "5.5.4", "version": "5.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
"dev": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"

View file

@ -8,11 +8,13 @@
<label for="username" class="form-label">{{t('username-label')}}</label> <label for="username" class="form-label">{{t('username-label')}}</label>
<input id="username" class="form-control custom-input" formControlName="username" type="text" autocomplete="username" <input id="username" class="form-control custom-input" formControlName="username" type="text" autocomplete="username"
[class.is-invalid]="registerForm.get('username')?.invalid && registerForm.get('username')?.touched" aria-describedby="username-validations"> [class.is-invalid]="registerForm.get('username')?.invalid && registerForm.get('username')?.touched" aria-describedby="username-validations">
<div id="username-validations" class="invalid-feedback" *ngIf="registerForm.dirty || registerForm.touched"> @if (registerForm.dirty || registerForm.touched) {
<div *ngIf="registerForm.get('username')?.errors?.required"> <div id="username-validations" class="invalid-feedback">
{{t('required-field')}} @if (registerForm.get('username')?.errors?.required) {
</div> <div>{{t('required-field')}}</div>
}
</div> </div>
}
</div> </div>
<div class="mb-3 text-start"> <div class="mb-3 text-start">
@ -22,16 +24,18 @@
<span class="visually-hidden" id="email-help"> <span class="visually-hidden" id="email-help">
<ng-container [ngTemplateOutlet]="emailTooltip"></ng-container> <ng-container [ngTemplateOutlet]="emailTooltip"></ng-container>
</span> </span>
<input class="form-control custom-input" type="email" inputmode="email" id="email" autocomplete="email" formControlName="email" required aria-describedby="email-help" <input class="form-control custom-input" type="email" inputmode="email" id="email" autocomplete="email" formControlName="email" aria-describedby="email-help"
[class.is-invalid]="registerForm.get('email')?.invalid && registerForm.get('email')?.touched"> [class.is-invalid]="registerForm.get('email')?.invalid && registerForm.get('email')?.touched">
<div id="email-validations" class="invalid-feedback" *ngIf="registerForm.dirty || registerForm.touched"> @if (registerForm.dirty || registerForm.touched) {
<div *ngIf="registerForm.get('email')?.errors?.required"> <div id="email-validations" class="invalid-feedback">
{{t('required-field')}} @if (registerForm.get('email')?.errors?.required) {
</div> <div>{{t('required-field')}}</div>
<div *ngIf="registerForm.get('email')?.errors?.email"> } @else if (registerForm.get('email')?.errors?.email) {
{{t('valid-email')}} <div>{{t('valid-email')}}</div>
</div> }
</div> </div>
}
</div> </div>
<div class="mb-3 text-start"> <div class="mb-3 text-start">

View file

@ -1,12 +1,12 @@
import {ChangeDetectionStrategy, Component, inject} from '@angular/core'; import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms'; import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {ToastrService} from 'ngx-toastr'; import {ToastrService} from 'ngx-toastr';
import {take} from 'rxjs/operators'; import {take} from 'rxjs/operators';
import {AccountService} from 'src/app/_services/account.service'; import {AccountService} from 'src/app/_services/account.service';
import {MemberService} from 'src/app/_services/member.service'; import {MemberService} from 'src/app/_services/member.service';
import {NgbTooltip} from '@ng-bootstrap/ng-bootstrap'; import {NgbTooltip} from '@ng-bootstrap/ng-bootstrap';
import { NgIf, NgTemplateOutlet } from '@angular/common'; import {NgTemplateOutlet} from '@angular/common';
import {SplashContainerComponent} from '../splash-container/splash-container.component'; import {SplashContainerComponent} from '../splash-container/splash-container.component';
import {translate, TranslocoDirective} from "@jsverse/transloco"; import {translate, TranslocoDirective} from "@jsverse/transloco";
import {NavService} from "../../../_services/nav.service"; import {NavService} from "../../../_services/nav.service";
@ -18,22 +18,25 @@ import {NavService} from "../../../_services/nav.service";
selector: 'app-register', selector: 'app-register',
templateUrl: './register.component.html', templateUrl: './register.component.html',
styleUrls: ['./register.component.scss'], styleUrls: ['./register.component.scss'],
imports: [SplashContainerComponent, ReactiveFormsModule, NgbTooltip, NgTemplateOutlet, TranslocoDirective],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [SplashContainerComponent, ReactiveFormsModule, NgIf, NgbTooltip, NgTemplateOutlet, TranslocoDirective]
}) })
export class RegisterComponent { export class RegisterComponent {
private readonly navService = inject(NavService);
private readonly router = inject(Router);
private readonly accountService = inject(AccountService);
private readonly toastr = inject(ToastrService);
private readonly memberService = inject(MemberService);
registerForm: FormGroup = new FormGroup({ registerForm: FormGroup = new FormGroup({
email: new FormControl('', [Validators.required]),
username: new FormControl('', [Validators.required]), username: new FormControl('', [Validators.required]),
email: new FormControl('', []),
password: new FormControl('', [Validators.required, Validators.maxLength(256), password: new FormControl('', [Validators.required, Validators.maxLength(256),
Validators.minLength(6), Validators.pattern("^.{6,256}$")]), Validators.minLength(6), Validators.pattern("^.{6,256}$")]),
}); });
private readonly navService = inject(NavService); constructor() {
constructor(private router: Router, private accountService: AccountService,
private toastr: ToastrService, private memberService: MemberService) {
this.navService.hideNavBar(); this.navService.hideNavBar();
this.navService.hideSideNav(); this.navService.hideSideNav();