Skip to main content

Posts

Showing posts with the label Angular

Defending yourself against compromised npm packages

The recent software supply-chain attacks proof once again that the npm ecosystem is a double-edged sword. With over 2 million packages available, developers can build applications faster than ever before. But this convenience comes with a significant security risk. When a single compromised package can affect thousands of downstream projects, we need better defenses. In this post, I'll show you how combining npm lock files with the --ignore-scripts flag creates a powerful security layer that can protect your projects from many common attack vectors. The growing threat of supply chain attacks Supply chain attacks in the npm ecosystem aren't theoretical—they're happening regularly. In recent years, we've seen high-profile incidents like the event-stream compromise, where a popular package was hijacked to steal Bitcoin wallets, and the ua-parser-js attack, where malicious code was injected to install cryptominers and password stealers. These attacks often follow a...

Angular 18–Referencing assets

Yesterday I wrote about a pet project I'm working that is using Angular 19. Turns out that some things have changed compared to previous versions. But where I discovered yesterday that a new build output structure was used, today I struggled with the handling of static assets. In older Angular versions, static application assets could be added to the src\assets folder and loaded from there in your application html. However starting from Angular 18 the src\assets folder is no longer there, instead a new assets option configuration exists in your angular.json . When creating a new project, this is configured by default to load assets from a public folder: The assets configuration is build up using a combination of 3 elements: glob: the pattern used to find matching files (e.g. **/*) input: the input directory where this pattern should be applied (e.g. public) output: the absolute path within the output where the matching assets should be copied to This confi...

Azure Static Web Apps - Failed to find a default file in the app artifacts folder. Valid default files: index.html,Index.html.

For a pet project I'm working on, I created a new Angular application using Angular 19. I used the same Github Actions setup I was using for my other projects. However, this time, the build failed with the following error message: Failed to find a default file in the app artifacts folder (dist/treasurehunt). Valid default files: index.html,Index.html. If your application contains purely static content, please verify that the variable 'app_location' in your workflow file points to the root of your application. If your application requires build steps, please validate that a default file exists in the build output directory. Here is the GitHub Actions file that was used: Important to notice here are the following settings: app_location: This is the location where the Azure Static Web App build task looks for the source code output_location: This is the location where the Azure Static Web App looks for the final application. This should match with your ...

Azure Static Web App - Authentication using pre-configured providers

As a follow-up on the presentation I did at  CloudBrew  about Azure Static Web Apps I want to write a series of blog posts. Part I - Using the VS Code Extension Part II - Using the Astro Static Site Generator Part III  – Deploying to multiple environments Part IV – Password protect your environments Part V – Traffic splitting Part VI(this post) – Authentication using pre-configured providers I ended 2023 with a post about protecting access to your Azure Static Web App using a password. Of course this is a poor man’s implementation of security. So let us have a look today on how to properly integrate authentication in our Azure Static Web App. Authentication in itself is a broad topic, we can further refine it in 2 parts: Who are you? The real authentication part What are you allowed to do? This is more a question of authorization instead of authentication Let us focus on the first question in this post. To allow a Static Web App to know who you are we nee...

Cloudbrew 2023–Azure Static Web Apps

Yesterday I had the honor to speak at CloudBrew , a 2 day conference organized by AZUG, the Belgium Microsoft Azure User Group. Last year I talked about Azure Application Insights , this year I did a presentation about Azure Static Web Apps. Again it was a really fun experience with great sessions, nice people, and the Gouden Carolus Triple at the end makes it perfect. I’m already looking forward to next year… Azure Static Web Apps – Too good to be true? As a lot of people are still unaware about Azure Static Web Apps(SWA) and the great things it had to offer, I decided to change this and brought a presentation sharing all the great things it had to offer. Discover the power of Azure Static Web Apps in this session, where we'll explore how it simplifies web development. Learn how to seamlessly integrate static front-end frameworks with serverless back-end APIs powered by Azure Functions. Explore features like effortless deployment, serverless back-end integration, cust...

Angular–Generate your OpenAPI client model

Most Angular applications need some kind of data typically provided through an OpenAPI or GraphQL API. Manually creating all the necessary model classes and client can be a time-consuming and error-prone task. In this post we have a look at ng-openapi-gen to help you automate this process. We start by installing the ng-openapi-gen module by executing the following command: npm install -g ng-openapi-gen Now we can generate our models and web client in the Angular application using the following command: ng-openapi-gen --input <path-to-openapi-json> --output <angular-app-path>/src/app/shared/api If you look at the command above you see that it requires to an OpenAPI specification file. This can be in JSON or YAML format. So we first need a way to get this specification file. If you are using ASP.NET Core with the OpenAPI integration , you can either download the OpenAPI file manually by going to the swagger UI and download it there or you can generate the OpenAPI...

Angular Cache

Last week I got a call from our operations team indicating that one of our build server disks was filling up. While investigating what could be the root cause, I noticed the .angular folder for each of our Angular frontend applications. I had no idea what this folder does, so let us find out together in this blog post… TLDR; The .angular folder is used by the Angular CLI to cache the previous builds to reduce the build operations and improves the build time. The .angular folder appeared in version 13 and is used as a disk cache by the Angular CLI to save a number of cachable operations on disk by default. When you re-run the same build, the build system restores the state of the previous build and re-uses previously performed operations, which decreases the time taken to build and test your applications and libraries. If we look what is inside, we see 2 things: An angular-webpack folder containing the binary files. A babel-webpack folder containing all the text fi...

Improve the build speed on your build server using npm ci

While looking at some of our Azure Pipelines, I noticed that some of our builds were really slow. So I opened up one of the slow builds and noticed that most time was spend installing npm packages. As we were using a local build agent, a first improvement you can make is to change the Clean settings to False so you don’t have to start with a clean working directory every time. Another improvement you can make is to switch from using npm install to npm ci . npm ci was introduced a few years ago and promised massive improvements to both the performance and reliability of builds for continuous integration / continuous deployment processes. It bypasses a package’s package.json to install modules from a package’s lockfile. This not only makes npm ci fast (sometimes twice as fast as using npm install ) it also helps to ensure reproducible builds—you are getting exactly what you expect on every install.

Angular production build error–Index html generation failed

A colleague asked me for help with a specific Angular build error he got. Everything was working fine during development but when he tried to create a production build using ng build --configuration production --aot it failed with the following error message Index html generation failed. Let's have a look at the configuration in the angular.json : If we compare this configuration with the development version the biggest difference between the two is that for production the optimization setting was enabled. Let’s have a look inside the documentation to see what this setting does: This option enables various optimizations of the build output, including: Minification of scripts and styles Tree-shaking Dead-code elimination Inlining of critical CSS Fonts inlining Aha! I could guess where the problem appears. As we had removed the index.html from our Angular project (we are not using the default index.html but have an ASP.NET Core MVC page that is u...

GraphQL Code Generator–Avoid generating types that are not needed

If you are using GraphQL in your frontend(or even backend) applications I hope you are not creating all the types yourself. Thanks to the built-in schema introspection functionality, tooling can do all the heavy-lifting for you. For frontend apps I typically use the GraphQL Code Generator created and maintained by The Guild . I don’t want to use this post to explain how to use the GraphQL Code Generator; there are multiple guides available. For example here is the one for Angular. Instead I want to focus on how you can manipulate the code generation. By default, the GraphQL Code Generator will generate types for your complete schema AND specific operation types based on the provided GraphQL queries/mutations/subscriptions. How does this looks like? Here is the codegen.ts file we are using: And here is on the GraphQL query files we are using: If we execute the codegeneration, we get types for the full schema: AND types for the specific operation: Generate only ope...

Disable TypeScript compilation in Visual Studio

I have an ASP.NET Core application with a corresponding Angular app. For convenience I host the Angular app as a part of the ASP.NET Core application. So I have the Angular TypeScript files as part of my solution: When I run the Angular build the output is copied to the wwwroot folder of the ASP.NET Core application: However by including the TypeScript files as part of my solution Visual Studio tries to compile my Angular application when I run a build. In this case this is not what I want as it resulted in the following errors: To fix it, I had to disable TypeScript compilaton. This can be done by adding the TypeScriptCompileBlocked property to your project file and set this to True :

Switch between node versions on Windows

By default, you have 1 node.js and NPM version installed on your machine. However, if you have to maintain applications written in multiple Angular and/or Typescript versions, this can become a problem. Older Angular/Typescript applications are not compatible with the latest node.js version and can no longer be compiled. In Linux, this has been solved by the introduction of nvm , the node version manager. With it, it is possible to quickly install(and uninstall) different node.js versions and easily switch between them via the command line. NVM-Windows With nvm-windows , an alternative is also available for Windows. You can easily install nvm-windows on your local machine via the installer available here: https://github.com/coreybutler/nvm-windows/releases . Using nvm-windows is very simple: Install a node.js version: nvm install <version> Listing the installed versions: nvm list Switching between versions: nvm use <version> No...

Azure Application Insights–Set cloud role name in Angular application

I've talked about how to setup Application Insights in an Angular application and also shared how to set the cloud role name in ASP.NET Core to improve the telemetry reporting. Let's build on top of these 2 posts and show you today how to update the cloud role name in an Angular application. We’ll start by extending our environment.ts file with an extra configuration setting to store the application name: Once that is done, we need to go the service ( app-insights.service.ts ) where we create our Application Insights instance. There we need to add a custom telemetry initializer by calling the addTelemetryInitializer method: Now when we run our Angular application, the cloud role name should be reported correctly to Application Insights.

Azure Application Insights–Angular integration

To get the most out of Application Insights when building a Single Page Application, some specific tweaks are required. Let's walk through the steps to get Application Insights configured in your Angular application. I expect that you already configured an Application Insights resource in the Azure Portal and have an existing Angular application. Step 1 -  Add dependencies and configuration settings We’ll start by adding an extra dependency ‘@microsoft/applicationinsights-web’ to our package.json: We also update our environment.ts file to store our Application Insights instrumentation key there: Step 2 – Create an Angular Service to wrap the Application Insights SDK We create an Angular service that we will use as a wrapper around the Application Insights SDK. Here we inject the AppInsights class. Notice that we set both the ‘enableCorsCorrelation’ and ‘enableAutoRouteTracking’ to true . This will correctly inject a correlation-id in our request headers and will ...

Angular - Refused to apply style from because its MIME type ('') is not a supported stylesheet MIME type

I t has been a while since the last time I did some web development using Angular. Today I had to troubleshoot an existing application, so I compiled the Angular code and opened my browser for a debugging session. First thing I noticed however was that although the Javascript code was executed succesfully, no CSS styling was applied. When I had a look at the browser errors I noticed the following error message: Refused to apply style from ' https://localhost:3000/assets/styles/style.css ' because its MIME type ('') is not a supported stylesheet MIME type, and strict MIME checking is enabled. Whoops! That was an error message that didn’t ring a bell. The error turned out to be more scary than the root cause of the issue. It turned out that the path to the CSS file was incorrect and that a 404 response was returned from the server.  I fixed the path and could happily continue debugging…

Angular --deploy-url and --base-href

As long you are running your Angular application at a root URL (e.g. www.myangularapp.com ) you don’t need to worry that much about either the ‘--deploy-url’ and ‘--base-href’ parameters. But once you want to serve your Angular application from a server sub folder(e.g. www.mywebsite.com/angularapp ) these parameters become important. --base-href If you deploy your Angular app to a subfolder, the ‘--base-href’ is important to generate the correct routes. This parameter will update the <base href> tag inside the index.html. For example, if the index.html is on the server at /angularapp/index.html , the base href should be set to <base href="/angularapp/"> . More information: https://angular.io/guide/deployment --deploy-url A second parameter that is important is ‘--deploy-url’. This parameter will update the generated url’s for our assets(scripts, css) inside the index.html. To make your assets available at /angularapp/, the deploy url should...

Angular 10–Strict mode

With the release of Angular 10 a more strict project setup is available. You can enable this by adding a –strict flag when creating a new Angular project: ng new --strict This strict mode allows to have more build-time optimizations, help to catch bugs faster and improves overall maintainability of your Angular application. Therefore it applies the following changes: Enables strict mode in TypeScript Turns template type checking to Strict Default bundle budgets have been reduced by ~75% Configures linting rules to prevent declarations of type any Configures your app as side-effect free to enable more advanced tree-shaking There is no out-of-the box option to enable this for an existing project(after creating it without the –strict flag or after upgrading from a previous version) but you can apply the same changes manually: Add the following rules to your tsconfig.json : "compilerOptions": { "strict": true, "fo...

Node issue–Call retries were exceeded

When trying to build an Angular 9 application on the build server, it failed on the ‘Generating ES5 bundles for differential loading’ step with the following error message: An unhandled exception occurred: Call retries were exceeded On the developer machines we couldn’t reproduce the issue (as always).  Inside the angular-errors.log we found the following extra details: [error] Error: Call retries were exceeded at ChildProcessWorker.initialize (\node_modules\@angular-devkit\build-angular\node_modules\jest-worker\build\workers\ChildProcessWorker.js:193:21) at ChildProcessWorker.onExit (\node_modules\@angular-devkit\build-angular\node_modules\jest-worker\build\workers\ChildProcessWorker.js:263:12) at ChildProcess.emit (events.js:210:5) at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12) We were able to solve the issue by upgrading the node version on the build server. Hopefully this helps for you as well…

Angular OIDC - Avoid token sharing

To integrate OIDC in our Angular applications we are using the great angular-oauth2-oidc library from Manfred Steyer. Once we receive a valid token back from our IdentityServer instance it is stored inside the session storage using the OAuthStorage class. This all seemed to work fine. However we got into trouble when we started to switch between applications. Different Angular apps were receiving a token from another app which resulted into errors. The problem had nothing to do with the angular-oauth2-oidc library but with the way we had setup our applications. All our applications where sharing the same root url and were hosted as virtual directories inside IIS; apps.example.com/app1 apps.example.com/app2 apps.example.com/app3 Session storage is scoped per domain but as all applications were using the same domain, they accidently accessed each other tokens. To fix it we had to create our own OAuthStorage class that used an application prefix to isolate the tok...

RxJS: Never subscribe in a subscription

During a code review of an Angular code base I noticed the following code snippet: What’s wrong with this code? We are subscribing inside a subscription. This makes it almost impossible to know what subscriptions are open at what moment. Good luck closing these subscriptions in the correct way(which you are doing, right?). A solution is to rewrite this code to use only 1 subscription. Closing this subscription will automatically clean up all inner streams. Let’s apply some RxJS magic to fix this: