3.0.1 • Published 3 months ago
@webundsoehne/register v3.0.1
Web & Söhne is Austria's leading expert in programming and implementing complex and large web projects.
Introduction
- The aim of this project is to provide an easy-to-use user authentication flow
- The process should be standardized as much as possible, but at the same time provide many possibilities for customization
- The provided module automatically provides several endpoints (each can be configured individually) for register, login, token refreshing, email confirmation and password reset (+ swagger documentation)
Requirements
- NestJS v8.0.0+
- Optional for Email queueing: One or many redis instance(s)
- Any (SQL) Database that is supported by TypeOrm (https://typeorm.io/#/)
Brief overview of endpoints
- After initializing the provided AuthModule (step-by-step description see below) the following endpoints will be attached automatically
Path | Usage | Method |
---|---|---|
/auth/register | Register new users | POST |
/auth/login | Login user (generate jwtToken and optionally refreshToken | POST |
/auth/email/validate/:token | Validate email token | GET |
/auth/confirmation/resend/:id | Resend email confirmation mail | POST |
/auth/password/reset/init | Initialize password reset | POST |
/auth/password/reset/check/:token | Check if provided password reset token is valid | GET |
/auth/password/reset/:token | Check if token is valid and reset password | POST |
/auth/password/validate | Check if a password meets all requirements | POST |
/auth/two-factor-auth/totp/enable | Enable TOTP two-factor-authentication for a user | POST |
/auth/two-factor-auth/totp/disable | Disable TOTP two-factor-authentication for a user | POST |
/auth/two-factor-auth/totp/verify | Login a user with TOTP two-factor-authentication | POST |
/auth/two-factor-auth/email/enable | Enable email two-factor-authentication for a user | POST |
/auth/two-factor-auth/email/disable | Disable email two-factor-authentication for a user | POST |
/auth/two-factor-auth/email/verify | Login a user with email two-factor-authentication | POST |
/auth/two-factor-auth/email/verify/init | Initiate email two-factor-authentication (sends the mail) | POST |
Step by Step Guide
- Initialize TypeOrm.forRoot() in your main module (not part of this module, but this packages needs a database connection)
- Create your own Entity and extend
UserEntity
provided by this package (and name all your additional properties etc.) - Create your own DTO and extend
RegisterDto
provided by this package (name your additional properties and make sure they match at least the required fields in your extended customUserEntity
) The providedUserEntity
automatically creates the following database schema for you
Name | Type | Usage |
---|---|---|
id | int | Unique user identifier |
varchar(255) | User's Email | |
password | varchar(255) | User's (hashed) password |
isBanned | tinyint(1) | Whether user is banned or not |
lastLogin | timestamp | Latest user's login |
emailVerifyToken | varchar(255) | User's (hashed) email verify token |
emailVerifyTokenValidUntil | timestamp | User's verify token expire date |
refreshToken | varchar(255) | User's (hashed) refresh token |
refreshTokenValidUntil | timestamp | User's refresh token expire date |
passwordResetToken | varchar(255) | User's password reset token |
passwordResetTokenValidUntil | timestamp | User's password reset token expire date |
passwordLastChanged | timestamp | Time the user last changed their password |
previousPasswords | text | User's previous (hashed) passwords, if enabled in config via denyPreviousPasswords |
failedLoginAttempts | int | Number of user's failed login attempts, reset to 0 after every successful login |
lastFailedLoginAttempt | timestamp | Time of user's last failed login attempt |
I would advise that you create your own entity even if you do not need additional fields
Sample code:
import { Entity } from 'typeorm'
import { UserEntity } from '@webundsoehne/register'
@Entity()
export class Customer extends UserEntity {
@Column({ nullable: false })
name: string
@Column()
city?: string | null
}
Sample code:
import { IsString, MaxLength } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { RegisterDto } from '@webundsoehne/register';
export class RegisterCustomerDto extends RegisterDto {
@ApiProperty({ type: String })
@IsString()
@MaxLength(255)
@IsDefined()
name: string;
}
- If you want to use TOTP/Email 2FA: Create your own Entity and extend
Totp2faEntity
/Email2faEntity
provided by this package. - Initialize provided AuthModule in your (main) module and configure it!
- There are lots of different options to customize the experience! Do not worry as it seems overwhelming at first, but it actually is quite straight forward!
- The sample code provides a minimal configuration object which should be enough!
import { AuthModule } from '@webundsoehne/register'
import { Customer } from './customer.entity'
@Module({
controllers: [],
imports: [
AuthModule.init({ queue: { useRedisQueue: false }, tokenOptions: { salt: 'secret' }, userEntity: Customer, registerDto: RegisterCustomerDto, email: { nodemailerOptions: { smtp: 'hallo.smtp.at', port: 1234, secure: false }, emailValidationRequired: true }})
],
providers: []
})
export class MainModule {}
Configuration object parameters (InitData)
- You can provide many different configuration options - I will explain them key by key, because I think that this is easier to grasp this way (instead of one huge table)
userEntity (REQUIRED)
- Provide your custom UserEntity (see above) here!
registerDto (NEW in v1.0.2)
- Provide your custom registerDto (see above) here!
- make sure to extend class
RegisterDto
- You can also manipulate these fields with interceptors if you need more complexity for your register endpoints
queue (RECOMMENDED)
- It is strongly advised to use NestJS Bull Queue (https://docs.nestjs.com/techniques/queues) for sending emails since email will be sent in a non-blocking manner - REQUIRES: one (or many) redis instance(s)!
- useRedisQueue (boolean): Whether or not to use NestJS Bull Queue (default: true)
- bullQueueOptions (BullModuleOptions): used to register NestJS Bull Queue (options see: (https://docs.nestjs.com/techniques/queues))
- bullJobOptions (JobOptions): these options will passed to each (email) job appended to queue
passwordResetSettings (OPTIONAL)
- Set TTL for password reset token (that's the time that will be appended to the token's creation date - after that duration the token is no longer valid and you have to request a new token)
- tokenDuration (number): Token TTL duration (default: 14)
- tokenUnit (DurationEnum): Token TTL unit (default: days)
emailTemplatesService (OPTIONAL)
- default: EmailTemplatesService
- See below for a detailed explanation about custom emailTemplateService
email (REQUIRED)
- emailValidationRequired (boolean): Whether or not the user has to validate their email address (click link in email address)
- tokenDuration (number): Token TTL duration (default: 14)
- tokenUnit (DurationEnum): Token TTL unit (default: days)
- nodemailerOptions (EmailConfigOptions): will be used to construct a nodemailer transport (https://nodemailer.com/about/)
- templateSettings (TemplateSettings): see below
templateSettings
- This settings will be used to generate email Template which will be sent on different occasions
- baseUri: baseUri for your frontend application
- applicationName: Name of your application
- validateEmail: (custom options) for email validation email
- validateEmail.subject: Subject of email validation mail
- validateEmail.frontendPath: path for your frontend (baseUri + frontendPath)
- validateEmail.from: from which email should it be sent from?
- resetPasswordPath: (custom options) for reset password email
- resetPasswordPath.subject: Subject of reset path mail
- resetPasswordPath.frontendPath: path for your frontend (baseUri + frontendPath)
- resetPasswordPath.from: from which email should it be sent from?
tokenOptions (REQUIRED)
- hashAlgorithm: which hash algorithm should be used to hash the generate (uuid) tokens (default: sha256)
- salt: additional salt which is appended to each (uuid) token before hashing (improves security) (default: thisisaverysecretsalt - but please make sure to overwrite this property!!)
refreshTokenOptions (OPTIONAL)
- tokenDuration (number): Token TTL duration (14)
- tokenUnit (DurationEnum): Token TTL unit (days)
passwordOptions (OPTIONAL)
- You can provide either minLength (then only minLength will be checked) or custom regular expression (REGEX) ==> overwrites minLength!
- minLength (number): Minimum length for password (is overwritten if you provide regex) (default: 7)
- errorMessage (string): Custom error message if password does not meet requirements (default: "Password does not satisfy requirements!")
- regex (string): Will be passed to Javascript RegExp constructor if set
- validityDuration (number): Determines after what time users are forced to update their passwords. (-1 = never) (default: -1)
- validityDurationUnit (DurationEnum): validityDuration unit (default: days)
- denyPreviousPasswords (number): Number of previous passwords that should be saved for each user. Users will be denied from changing their password to one of the old ones (default: 0)
- blacklist:
- enabled (boolean): Whether a password blacklist should be used for password validation. At least one of the two following options have to be provided when enabled. (default: false)
- filePath (string): Path to a text file with blacklisted passwords (one password per line).
- url (string): Url to a text file with blacklisted passwords (e.g.: https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Common-Credentials/10k-most-common.txt)
securityOptions (OPTIONAL)
- accountLockoutThreshold (number): Number of times a user can enter wrong credentials before the account gets locked. Durations can be provided via accountLockoutDurations. (-1 = infinite times) (default: -1)
- accountLockoutDurations (number[]): Number of minutes an account should get locked after exceeding the lockoutThreshold. On every continuously failed login attempt, the index will be increased by one. E.g.:
[1, 5, -1]
will lock out accounts for 1 minute initially, 5 minutes after another failed login attempt, and forever (-1 = forever) after a third failed login attempt. If the number of continuously failed login attempts exceeds the length of this array, the last duration will be used. Index will be reset on successful login. (default: -1)
jwtPayloadFields (OPTIONAL)
- string | string[]
- Specify all the database fields which should be your jwt token's payload!
- if you just pass a string instead of a string array all the fields will be appended to JWT payload
- Basically the fields you specify here will later be accessible by
JwtUser
decorator in your routes! - Default:
[id, email]
jwtOptions (REQUIRED)
- JwtModuleOptions
- jwtOptions.secret -> secret used for jwtToken please make sure to overwrite this! (default: 'thisisaverysecretstring')
- jwtOptions.signOptions.expiresIn -> how long is jwtToken valid? (default: 1h)
- There are many more options which you can find either via interface or https://github.com/auth0/node-jsonwebtoken#usage
jwtStrategyOptions
- All possible options: https://github.com/mikenicholson/passport-jwt#configure-strategy
jwtSignOptions
- Used to sign jwt tokens
routes
- This option can be used to configure the different routes
- Detailed explanation of each endpoint see above: they all come with a prefix of
/auth
- registerUser (
/register
) - loginUser (
/login
) - refreshToken (
/refresh
) - validateEmail (
/email/validate/:token
) - resendConfirmation (
/confirmation/resend/:id
) - initPasswordReset (
/password/reset/init
) - checkPasswordResetToken (
/password/reset/check/:token
) - checkPasswordResetTokenAndSetPassword (
/password/reset/:token
) - validatePassword (
/password/validate
) - enable2faTotp (
/two-factor-auth/totp/enable
) - disable2faTotp (
/two-factor-auth/totp/disable
) - verify2faTotp (
/two-factor-auth/totp/verify
) - enable2faEmail (
/two-factor-auth/email/enable
) - disable2faEmail (
/two-factor-auth/email/disable
) - verify2faEmail (
/two-factor-auth/email/verify
) - initVerify2faEmail (
/two-factor-auth/email/verify/init
)
RouteConfig object
- each route can be configured with these options
- endpointPath (string): change path of endpoint (if you ever want to change the endpoint path and there are placeholders (for token, id etc.) make sure to include them as well or otherwise the endpoint will not function correctly anymore!)
- method (RequestMethod): request method (I would not recommend to ever change it)
- interceptors (NestJS Interceptor): NestJS Interceptors that should be registered for this endpoint
- enable (boolean): whether or not the endpoint should be enabled
EmailTemplateService
- There are 2 emails which will be sent out to the user automatically
- These emails are not really fancy but they function well
- You probably want to create your own templates (with your company's logo custom text etc.). This can be done by providing your own emailTemplateService to
init
method ofAuthModule
- Optionally your interface can inject the whole config object (that you provide while initializing
AuthModule
) (see example below) - Just create a Service that extends
EmailTemplatesService
and (optionally) implements provided interfaceEmailTemplatesInterface
and just import it as provider in your main module! - Each method is called with data of interface
TokenData
and expects a Promise which resolves to data of typeEmail
interface
TokenData interface
- token: uuid token used to identify user
- email: user's email
- tokenValidUntil: timestamp until the token is valid
Email interface
- from (string) (REQUIRED): Sender's email address
- to (string) (REQUIRED): Recipient's email address
- subject (string) (REQUIRED): Email's subject
- text (string) (REQUIRED): Email's text
- bcc (string) (OPTIONAL): Email's bcc
- cc (string) (OPTIONAL): Email's cc
- html (string) (OPTIONAL): Email's HTML text
- attachments (EmailAttachment[]) (OPTIONAL): Optional email attachments (base64 format)
Welcome email
- Sent after user registration
- include token which can be used to validate user's email
Password reset email
- Sent after user requests password reset
- include token which can be used to validate user's email
Example for custom emailTemplateService
- Make sure to import this as a provider in your main module and set
emailTemplateService
option (forAuthModule.init(...))
!)
import { Inject, Injectable, Optional } from '@nestjs/common'
import { InitData, Email, TokenData, EmailTemplatesInterface, EmailTemplatesService } from '@webundsoehne/register'
@Injectable()
export class CustomEmailTemplatesService extends EmailTemplatesService implements EmailTemplatesInterface {
constructor (@Optional() @Inject(CONFIG_TOKEN) private config: InitData) {}
async getWelcomeMailTemplate (data: TokenData): Promise<Email> { ... }
async getPasswordResetInitMailTemplate (data: TokenData): Promise<Email> { ... }
}
TwoFactorAuth (OPTIONAL)
- enabled (boolean): whether or not two-factor-authentication should be enabled (default: false)
- encryptionKey (string): A 32 byte encryption key that is used to encrypt sensitive information (e.g, totp secret).
Time-based one-time password (TOTP)
- providers.totp:
- enabled (boolean): Whether or not the TOTP provider should be enabled (default: false).
- numberOfRecoveryCodes (number): The number of recovery codes that should be generated for a user (default: 5).
- tokenValidFor (number): The interval in seconds that a generated token should be valid for (default: 30).
- tokenWindow (number): The number of additional consecutive tokens of the past/future that should count as valid (default: 1).
- qrCodeIssuer (string): A string that will be encoded into the QR Code that is generated when TOTP is enabled for a user. It is usually displayed in authenticator apps.
- totp2faEntity: The Totp2faEntity that should be used.
Token via E-Mail (EMAIL)
- providers.email:
- enabled (boolean): Whether or not the email provider should be enabled (default: false).
- numberOfRecoveryCodes (number): The number of recovery codes that should be generated for a user (default: 5).
- tokenValidFor (number): The interval in minutes that a generated token should be valid for (default: 15).
- numberOfTokenCharacters (number): The number of characters (a-z0-9) that a generated token should have (default: 6).
- mailTimeout (number): The minimum number of seconds that a user has to wait before initiating another mail (default: 20).
- email2faEntity: The Email2faEntity that should be used.
Stay in touch
- Do you have any additional questions?
- Author: Backend Team; Markus Schüttengruber
- Website: Web & Söhne
4.0.0-beta.3
3 months ago
5.0.0
3 months ago
4.0.0
4 months ago
3.0.1
2 years ago
4.0.0-beta.2
1 year ago
4.0.0-beta.1
1 year ago
4.0.0-beta.0
1 year ago
3.0.0
2 years ago
2.0.2
2 years ago
2.0.1
2 years ago
2.0.0
2 years ago
1.1.4
3 years ago
1.1.3
3 years ago
1.1.2
3 years ago
1.1.1
3 years ago
1.1.0
3 years ago
1.0.4
3 years ago
1.0.3
4 years ago
1.0.2
4 years ago
1.0.1
4 years ago
1.0.0
4 years ago
0.0.1
4 years ago