npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@notiz/nest-auth-formly

v0.2.0

Published

Nest Auth UI with TailwindCSS and Formly for Angular

Downloads

271

Readme

NestAuthFormly

npm version

Works together with nest-auth

Installation

Requires Tailwind, Tailwind Forms Plugin, Formly and Tailwind-Formly

# select forms plugin
ng add ngx-tailwind

# alternative install via
npm install -D @tailwindcss/forms

ng add @ngx-formly/schematics
# or
npm i @ngx-formly/core

npm i @notiz/formly-tailwindcss

Your AppModule should look like this and import HttpClientModule

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ReactiveFormsModule } from '@angular/forms';
import { FormlyModule } from '@ngx-formly/core';
import { FormlyTailwindcssModule } from '@notiz/formly-tailwindcss';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule,
    FormlyModule.forRoot({
      extras: { lazyRender: true },
    }),
    FormlyTailwindcssModule,
    HttpClientModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Now install ... NOT YET AVAILABLE

Nest Application works great with code generators such as ng-openapi-gen for Rest or graphql-code-generator for GraphQL to create Angular services for your endpoints.

Usage

NestAuthFormlyModule

Import NestAuthFormlyModule which includes JwtInterceptor, read more about Interceptor.

import { environment } from '@env/environment';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { FormlyModule } from '@ngx-formly/core';
import { FormlyTailwindcssModule } from '@notiz/formly-tailwindcss';

import { NestAuthFormlyModule } from '@notiz/nest-auth-formly';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule,
    FormlyModule.forRoot({
      extras: { lazyRender: true },
      validationMessages: [{ name: 'required', message: 'Is required' }],
    }),
    FormlyTailwindcssModule,
    HttpClientModule,
    NestAuthFormlyModule.forRoot({
      httpInterceptor: {
        // attaches access token only to the allowed endpoints
        allowedList: [
          // `${environment.baseUrl}/users/me`,
          // `${environment.baseUrl}/graphql`,
          `${environment.baseUrl}/*`,
        ],
      },
    }),
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Social Login

To add social login buttons via formly import SocialLoginModule to register formly type socialLogin.

import { environment } from '@env/environment';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { FormlyModule } from '@ngx-formly/core';
import { FormlyTailwindcssModule } from '@notiz/formly-tailwindcss';

import { NestAuthFormlyModule } from '@notiz/nest-auth-formly';
import { SocialLoginModule } from '@notiz/nest-auth-formly/social';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule,
    FormlyModule.forRoot({
      extras: { lazyRender: true },
      validationMessages: [{ name: 'required', message: 'Is required' }],
    }),
    FormlyTailwindcssModule,
    HttpClientModule,
    NestAuthFormlyModule,
    SocialLoginModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Interceptor

JwtInterceptor adds the access token, if available, to the request as Authorization Bearer token.

Import NestAuthFormlyModule or add JwtInterceptor as a provider

import { environment } from '@env/environment';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ReactiveFormsModule } from '@angular/forms';
import { FormlyModule } from '@ngx-formly/core';
import { FormlyTailwindcssModule } from '@notiz/formly-tailwindcss';
import { JwtInterceptor } from '@notiz/nest-auth-formly';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule,
    FormlyModule.forRoot({
      extras: { lazyRender: true },
      validationMessages: [{ name: 'required', message: 'Is required' }],
    }),
    FormlyTailwindcssModule,
    HttpClientModule,
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

Guards

AuthGuard protects your routes from not authenticated users.

import { AuthGuard } from '@notiz/nest-auth-formly';

const routes: Routes = [
  { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
  {
    path: 'login',
    loadChildren: () =>
      import('./auth/login/login.module').then((m) => m.LoginModule),
  },
  {
    path: 'dashboard',
    loadChildren: () =>
      import('./dashboard/dashboard.module').then((m) => m.DashboardModule),
    canActivate: [AuthGuard],
  },
];

Customize Guard behavior

Customize the behavior of AuthGuard by passing an rxJS pipe through the route data's authGuardPipe key.

The following pre-built pipes are available:

| Pipes |  Description | | ------------------------ | -------------------------------------------------------------- | | loggedIn | The default pipe, rejects if the user is not authenticated | | hasRole | Rejects authenticated users without specific role | | hasRoleOf | Rejects authenticated users without one of the specified roles | | emailVerified | Rejects authenticated users without verified email | | redirectLoggedInTo | Redirect authenticated users to a different route | | redirectUnauthorizedTo | Redirect unauthenticated users to a different route |

Example use:

import {
  AuthGuard,
  loggedIn,
  redirectLoggedInTo,
  redirectUnauthorizedTo,
} from '@notiz/nest-auth-formly';

const routes: Routes = [
  { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
  {
    path: 'login',
    loadChildren: () =>
      import('./auth/login/login.module').then((m) => m.LoginModule),
    canActivate: [AuthGuard],
    data: { authGuardPipe: () => redirectLoggedInTo(['']) },
  },
  {
    path: 'profile',
    loadChildren: () =>
      import('./profile/profile.module').then((m) => m.ProfileModule),
    canActivate: [AuthGuard],
    data: { authGuardPipe: () => loggedIn }, // Default behavior of AuthGuard
  },
  {
    path: 'dashboard',
    loadChildren: () =>
      import('./dashboard/dashboard.module').then((m) => m.DashboardModule),
    canActivate: [AuthGuard],
    data: { authGuardPipe: () => redirectUnauthorizedTo(['login']) },
  },
  {
    path: 'admin',
    loadChildren: () =>
      import('./admin/admin.module').then((m) => m.AdminModule),
    canActivate: [AuthGuard],
    data: { authGuardPipe: () => hasRole('ADMIN') },
  },
];

Use canActivate helper and spread syntax to make your routes more readable:

import {
  AuthGuard,
  canActivate
  loggedIn,
  redirectLoggedInTo,
  redirectUnauthorizedTo,
} from '@notiz/nest-auth-formly';

const routes: Routes = [
  { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
  {
    path: 'login',
    loadChildren: () =>
      import('./auth/login/login.module').then((m) => m.LoginModule),
    ...canActivate(() => redirectLoggedInTo(['']))
  },
  {
    path: 'profile',
    loadChildren: () =>
      import('./profile/profile.module').then((m) => m.ProfileModule),
    ...canActivate(() => loggedIn([''])) // Default behavior of AuthGuard
  },
  {
    path: 'dashboard',
    loadChildren: () =>
      import('./dashboard/dashboard.module').then((m) => m.DashboardModule),
    ...canActivate(() => redirectUnauthorizedTo(['login'])),
  },
  {
    path: 'admin',
    loadChildren: () =>
      import('./admin/admin.module').then((m) => m.AdminModule),
    ...canActivate(() => hasRole('ADMIN')),
  },
];

Compose your own pipes

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { canActivate, hasRole } from '@notiz/nest-auth-formly';
import { pipe } from 'rxjs';

const adminOnly = pipe(hasRole('ADMIN'));

const routes: Routes = [
  ...{
    path: 'admin',
    loadChildren: () =>
      import('./admin/admin.module').then((m) => m.AdminModule),
    ...canActivate(() => adminOnly),
  },
];

Using router state

const onlyAllowSelf = (next) =>
  map((user) => !!user && next.params.userId === user.id);

Development

Start the demo of nest-auth

npm i

ng s

# generate rest
npm run codegen:rest
# generate graphql
npm run codegen:graphql