I'm trying something new and that would be using ASP.NET Core as my backend while using Angular for the frontend. While the backend was a breeze to configure, the frontend haven't been as close. When I try running the application, I receive the following errors in teh console:
> integrafechado@0.0.0 prestart
> node aspnetcore-https
> integrafechado@0.0.0 start
> run-script-os
> integrafechado@0.0.0 start:windows
> ng serve --port 44488 --ssl --ssl-cert "%APPDATA%\ASP.NET\https\%npm_package_name%.pem" --ssl-key "%APPDATA%\ASP.NET\https\%npm_package_name%.key"
Initial Chunk Files   | Names         |  Raw Size
vendor.js             | vendor        |   3.03 MB |
styles.css, styles.js | styles        | 440.48 kB |
polyfills.js          | polyfills     | 434.76 kB |
main.js               | main          | 181.56 kB |
runtime.js            | runtime       |   6.53 kB |
                      | Initial Total |   4.07 MB
Build at: 2023-06-12T15:15:32.894Z - Hash: bdb0de9435970ca7 - Time: 2757ms
Error: src/api-authorization/login/login.component.html:6:13 - error NG8002: Can't bind to 'formGroup' since it isn't a known property of 'form'.
6             [formGroup]="loginForm"
              ~~~~~~~~~~~~~~~~~~~~~~~
  src/api-authorization/login/login.component.ts:16:15
    16  templateUrl: "./login.component.html",
                     ~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component LoginComponent.
Error: src/api-authorization/login/login.component.html:6:26 - error TS2339: Property 'loginForm' does not exist on type 'LoginComponent'.
6             [formGroup]="loginForm"
                           ~~~~~~~~~
  src/api-authorization/login/login.component.ts:16:15
    16  templateUrl: "./login.component.html",
                     ~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component LoginComponent.
Error: src/api-authorization/login/login.component.html:7:25 - error TS2341: Property 'login' is private and only accessible within class 'LoginComponent'.
7             (ngSubmit)="login(loginForm.value)"
                          ~~~~~
  src/api-authorization/login/login.component.ts:16:15
    16  templateUrl: "./login.component.html",
                     ~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component LoginComponent.
Error: src/api-authorization/login/login.component.html:7:31 - error TS2339: Property 'loginForm' does not exist on type 'LoginComponent'.
7             (ngSubmit)="login(loginForm.value)"
                                ~~~~~~~~~
  src/api-authorization/login/login.component.ts:16:15
    16  templateUrl: "./login.component.html",
                     ~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component LoginComponent.
Error: src/api-authorization/login/login.component.html:69:1 - error NG8001: 'app-footer' is not a known element:
1. If 'app-footer' is an Angular component, then verify that it is part of this module.
2. If 'app-footer' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
69 <app-footer></app-footer>
   ~~~~~~~~~~~~
  src/api-authorization/login/login.component.ts:16:15
    16  templateUrl: "./login.component.html",
                     ~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component LoginComponent.
** Angular Live Development Server is listening on localhost:44488, open your browser on https://localhost:44488/ **
× Failed to compile.
Here's the login.component.html file:
<div class="login-container">
  <div id="container-main" class="login-container-main">
    <label id="login-label" for="login-form" class="login-text">Login</label>
    <div id="container-form" class="login-container-form">
      <form id="login-form"
            [formGroup]="loginForm"
            (ngSubmit)="login(loginForm.value)"
            name="login-form"
            target="self"
            enctype="application/x-www-form-urlencoded"
            class="login-form">
        <div class="login-container-labels">
          <div id="email-label-div" class="login-container1">
            <label id="email-label" for="email-input" class="login-text1">
              E-mail
            </label>
          </div>
          <div id="senha-label-div" class="login-container2">
            <label id="password-label" for="password-input" class="login-text2">
              Senha
            </label>
          </div>
          <div id="register-div" class="login-container3">
            <label id="noregister-label"
                   for="register-button"
                   class="login-text3">
              Não tem conta?
            </label>
            <button id="register-button"
                    name="register-button"
                    type="button"
                    class="login-button Link button">
              Registrar
            </button>
          </div>
        </div>
        <div class="login-container-inputs">
          <div id="email-input-div" class="login-container4">
            <input formControlName="email"
                   type="email"
                   id="email-input"
                   required
                   autofocus
                   placeholder="exemplo@exemplo.com"
                   class="input" />
          </div>
          <div id="senha-input-div" class="login-container5">
            <input formControlName="password"
                   type="password"
                   id="password-input"
                   required
                   minlength="8"
                   placeholder="Sua senha"
                   class="input" />
          </div>
          <div id="login-div" class="login-container6">
            <button type="submit" class="login-button1 button">
              <span class="login-text4">
                <span class="login-text5">Logar</span>
                <br />
              </span>
            </button>
          </div>
        </div>
      </form>
    </div>
  </div>
</div>
<app-footer></app-footer>
login.module.ts:
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { FooterComponent } from "./footer.component";
@NgModule({
    declarations: [
        FooterComponent
    ],
    imports: [
        CommonModule
    ],
    exports: [
        FooterComponent
    ]
})
export class FooterModule { }
login.component.ts:
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-useless-escape */
/* eslint-disable no-case-declarations */
import { Component, OnInit } from "@angular/core";
import { AuthorizeService, AuthenticationResultStatus } from "../authorize.service";
import { ActivatedRoute, Router } from "@angular/router";
import { BehaviorSubject } from "rxjs";
import { LoginActions, QueryParameterNames, ApplicationPaths, ReturnUrlType } from "../api-authorization.constants";
// The main responsibility of this component is to handle the user's login process.
// This is the starting point for the login process. Any component that needs to authenticate
// a user can simply perform a redirect to this component with a returnUrl query parameter and
// let the component perform the login and return back to the return url.
@Component({
    selector: "app-login",
    templateUrl: "./login.component.html",
    styleUrls: ["./login.component.css"]
})
export class LoginComponent implements OnInit {
    public message = new BehaviorSubject<string | null | undefined>(null);
    constructor(
    private authorizeService: AuthorizeService,
    private activatedRoute: ActivatedRoute,
    private router: Router) { }
    async ngOnInit() {
        const action = this.activatedRoute.snapshot.url[1];
        switch (action.path) {
        case LoginActions.Login:
            await this.login(this.getReturnUrl());
            break;
        case LoginActions.LoginCallback:
            await this.processLoginCallback();
            break;
        case LoginActions.LoginFailed:
            const message = this.activatedRoute.snapshot.queryParamMap.get(QueryParameterNames.Message);
            this.message.next(message);
            break;
        case LoginActions.Profile:
            this.redirectToProfile();
            break;
        case LoginActions.Register:
            this.redirectToRegister();
            break;
        default:
            throw new Error(`Invalid action '${action}'`);
        }
    }
    private async login(returnUrl: string): Promise<void> {
        const state: INavigationState = { returnUrl };
        const result = await this.authorizeService.signIn(state);
        this.message.next(undefined);
        switch (result.status) {
        case AuthenticationResultStatus.Redirect:
            break;
        case AuthenticationResultStatus.Success:
            await this.navigateToReturnUrl(returnUrl);
            break;
        case AuthenticationResultStatus.Fail:
            await this.router.navigate(ApplicationPaths.LoginFailedPathComponents, {
                queryParams: { [QueryParameterNames.Message]: result.message }
            });
            break;
        default:
            throw new Error(`Invalid status result ${(result as any).status}.`);
        }
    }
    private async processLoginCallback(): Promise<void> {
        const url = window.location.href;
        const result = await this.authorizeService.completeSignIn(url);
        switch (result.status) {
        case AuthenticationResultStatus.Redirect:
            // There should not be any redirects as completeSignIn never redirects.
            throw new Error("Should not redirect.");
        case AuthenticationResultStatus.Success:
            await this.navigateToReturnUrl(this.getReturnUrl(result.state));
            break;
        case AuthenticationResultStatus.Fail:
            this.message.next(result.message);
            break;
        }
    }
    private redirectToRegister(): any {
        this.redirectToApiAuthorizationPath(
            `${ApplicationPaths.IdentityRegisterPath}?returnUrl=${encodeURI("/" + ApplicationPaths.Login)}`);
    }
    private redirectToProfile(): void {
        this.redirectToApiAuthorizationPath(ApplicationPaths.IdentityManagePath);
    }
    private async navigateToReturnUrl(returnUrl: string) {
        // It's important that we do a replace here so that we remove the callback uri with the
        // fragment containing the tokens from the browser history.
        await this.router.navigateByUrl(returnUrl, {
            replaceUrl: true
        });
    }
    private getReturnUrl(state?: INavigationState): string {
        const fromQuery = (this.activatedRoute.snapshot.queryParams as INavigationState).returnUrl;
        // If the url is coming from the query string, check that is either
        // a relative url or an absolute url
        if (fromQuery &&
      !(fromQuery.startsWith(`${window.location.origin}/`) ||
        /\/[^\/].*/.test(fromQuery))) {
            // This is an extra check to prevent open redirects.
            throw new Error("Invalid return url. The return url needs to have the same origin as the current page.");
        }
        return (state && state.returnUrl) ||
      fromQuery ||
      ApplicationPaths.DefaultLoginRedirectPath;
    }
    private redirectToApiAuthorizationPath(apiAuthorizationPath: string) {
        // It's important that we do a replace here so that when the user hits the back arrow on the
        // browser they get sent back to where it was on the app instead of to an endpoint on this
        // component.
        const redirectUrl = `${window.location.origin}/${apiAuthorizationPath}`;
        window.location.replace(redirectUrl);
    }
}
interface INavigationState {
  [ReturnUrlType]: string;
}
and finally, footer.module.ts:
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { FooterComponent } from "./footer.component";
@NgModule({
    declarations: [
        FooterComponent
    ],
    imports: [
        CommonModule
    ],
    exports: [
        FooterComponent
    ]
})
export class FooterModule { }
I'm not completely sure about what is right or wrong, VS2022 creates the new project with the base for authentication in a folder called api-authorization, but I tried using Angular's forms, although ASP.NET Core handles authentication with the middlewares. As far as I've seen, you have to create the login template for the application. Is there a simpler way to use the created login html? I'd be happy to provide more details if needed
