@peersyst/auth-module
TypeScript icon, indicating that this package has built-in type declarations

0.14.3 • Public • Published

Nest Logo

A progressive Node.js framework for building efficient and scalable server-side applications.

NPM Version Package License NPM Downloads CircleCI Coverage Discord Backers on Open Collective Sponsors on Open Collective Support us

Description

Nest framework TypeScript base auth module.

Installation

$ npm install --save @peersyst/auth-module

How to use it

Base auth module (no 3rd party logins or 2fa)

  • Import and register AuthModule in AppModule
import { AuthModule } from "@peersyst/auth-module";

@Module({
    imports: [
        ConfigModule.forRoot(...),
        TypeOrmModule.forRootAsync(...),
        UserModule,
        AuthModule.register(UserModule, ConfigModule, ConfigService, {}),
    ],
})
export class AppModule {}
  • UserModule should export a provider named UserService
@Module({
    imports: [
        TypeOrmModule.forFeature([User]),
    ],
    providers: [MyUserService, { provide: "UserService", useClass: MyUserService }],
    controllers: [UserController],
    exports: [MyUserService, { provide: "UserService", useClass: MyUserService }, TypeOrmModule],
})
export class UserModule {}
  • Add configService configuration variables
export default (): any => ({
    server: {
        secretKey: process.env.APP_JWT_KEY, ...
    },
});
  • Add AuthErrorCode and AuthErrorBody to app ErrorCodes
import { HttpStatus } from "@nestjs/common";
import { AuthErrorCode, AuthErrorBody } from "@peersyst/auth-module";

// Define app error codes
enum AppErrorCode {}

export const ErrorCode = { ...AppErrorCode, ...AuthErrorCode };
export type ErrorCodeType = AppErrorCode | AuthErrorCode;

export const ErrorBody: { [code in ErrorCodeType]: { statusCode: HttpStatus; message: string } } = {
    // Define app error code bodies
    ...AuthErrorBody,
};
  • Implement AuthUserI for User entity
import { AuthUserI, UserType } from "@peersyst/auth-module";

@Entity("user")
export class User implements AuthUserI {...}
  • Implement AuthUserServiceI for UserService
import { AuthUserServiceI } from "@peersyst/auth-module";

@Injectable()
export class UserService implements AuthUserServiceI {...}
  • Use authenticated in controllers
import { Authenticated } from "@peersyst/auth-module";

@ApiTags("user")
@Controller("users")
@ApiErrorDecorators()
export class UserController {
    constructor(private readonly userService: UserService) {}

    @Authenticated(UserType.ADMIN)
    @Post("create")
    @ApiOperation({ summary: "Create user" })
    async create(@Body() createUserRequestDto: CreateUserRequest): Promise<UserDto> {
        return this.userService.createUser(createUserRequestDto);
    }

    @Authenticated()
    @Get("info")
    @ApiOperation({ summary: "Show user info" })
    // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
    async info(@Request() req): Promise<UserDto> {
        return this.userService.findById(req.user.id);
    }
}

Add Google login

  • Set googleAuth to true in register module
AuthModule.register(UserModule, ConfigModule, ConfigService, {
    googleAuth: true,
}),
  • Add configService configuration variables
export default (): any => ({
    server: {
        secretKey: process.env.APP_JWT_KEY,
        frontUrl: process.env.FRONT_URL,
        baseUrl: process.env.BASE_URL,
    },
    googleAuth: {
        clientId: process.env.GOOGLE_AUTH_CLIENT_ID,
        clientSecret: process.env.GOOGLE_AUTH_CLIENT_SECRET,
    },
});
  • Implement AuthGoogleUserI for User entity
import { AuthUserI, AuthGoogleUserI, UserType } from "@peersyst/auth-module";

@Entity("user")
export class User implements AuthUserI, AuthGoogleUserI {...}
  • Implement ThirdPartyUserServiceI for UserService
import { AuthUserServiceI, ThirdPartyUserServiceI } from "@peersyst/auth-module";

@Injectable()
export class UserService implements AuthUserServiceI, ThirdPartyUserServiceI {...}

Add Twitter login

  • Set twitterAuth to true in register module
AuthModule.register(UserModule, ConfigModule, ConfigService, {
    twitterAuth: true,
}),
  • Add configService configuration variables
export default (): any => ({
    server: {
        secretKey: process.env.APP_JWT_KEY,
        frontUrl: process.env.FRONT_URL,
        baseUrl: process.env.BASE_URL,
    },
    twitterAuth: {
        apiKey: process.env.TWITTER_API_KEY,
        apiKeySecret: process.env.TWITTER_API_KEY_SECRET,
    },
});
  • Implement AuthTwitterUserI for User entity
import { AuthUserI, AuthTwitterUserI, UserType } from "@peersyst/auth-module";

@Entity("user")
export class User implements AuthUserI, AuthTwitterUserI {...}
  • Implement ThirdPartyUserServiceI for UserService
import { AuthUserServiceI, ThirdPartyUserServiceI } from "@peersyst/auth-module";

@Injectable()
export class UserService implements AuthUserServiceI, ThirdPartyUserServiceI {...}

Add Validate email

  • Set validateEmail to true in register module
AuthModule.register(UserModule, ConfigModule, ConfigService, {
    validateEmail: true,
}),
  • Implement ValidateEmailUserServiceI for UserService
import { AuthUserServiceI, ValidateEmailUserServiceI } from "@peersyst/auth-module";

@Injectable()
export class UserService implements AuthUserServiceI, ValidateEmailUserServiceI {...}
  • When you either create or register a user an email verification token should be created and sent:
import { AuthUserServiceI, ValidateEmailUserServiceI, TokenService } from "@peersyst/auth-module";

@Injectable()
export class UserService implements AuthUserServiceI, ValidateEmailUserServiceI {
    constructor(
        @InjectRepository(User) private readonly userRepository: Repository<User>,
        @Inject(NotificationService) private readonly notificationService: NotificationService,
        @Inject(ValidateEmailService) private readonly validateEmailService: ValidateEmailService,
    ) {}
    
    async registerUser(registerUserRequest: RegisterUserRequest): Promise<PrivateUserDto> {
        const entity = await this.userRepository.save(registerUserRequest);
        const user = PrivateUserDto.fromEntity(entity);
        const token = await this.validateEmailService.createEmailVerificationToken(user.id);
        await this.notificationService.sendEmailVerificationMessage(createUserRequest.email, token);
    }
}
  • Create entity in your entities folder with name VerifyEmailToken
export { VerifyEmailToken } from "@peersyst/auth-module";

Add Recover Password

  • Set recoverPassword to true in register module and indicate NotificationModule.
AuthModule.register(UserModule, ConfigModule, ConfigService, {
    recoverPassword: true,
    NotificationModule,
}),

NotificationModule should export a provider named NotificationService (v8 onwards):

@Module({
    providers: [NotificationService, { provide: "NotificationService", useClass: NotificationService }],
    exports: [NotificationService, { provide: "NotificationService", useClass: NotificationService }],
})
export class NotificationModule {}
  • Implement RecoverNotificationServiceI for NotificationService
import { RecoverNotificationServiceI } from "@peersyst/auth-module";

@Injectable()
export class NotificationService implements RecoverNotificationServiceI {...}
  • Implement RecoverPasswordUserServiceI for UserService
import { AuthUserServiceI, RecoverPasswordUserServiceI } from "@peersyst/auth-module";

@Injectable()
export class UserService implements AuthUserServiceI, RecoverPasswordUserServiceI {...}
  • Create entity in your entities folder with name ResetToken
export { ResetToken } from "@peersyst/auth-module";

Add 2 Factor Authenticated (work in progress)

  • Set twoFA to true in register module
AuthModule.register(UserModule, ConfigModule, ConfigService, {
    twoFA: true,
}),
  • Implement Auth2FAUserI for User entity
import { AuthUserI, Auth2FAUserI, UserType } from "@peersyst/auth-module";

@Entity("user")
export class User implements AuthUserI, Auth2FAUserI {...}

License

Nest is MIT licensed.

Readme

Keywords

none

Package Sidebar

Install

npm i @peersyst/auth-module

Weekly Downloads

637

Version

0.14.3

License

none

Unpacked Size

402 kB

Total Files

188

Last publish

Collaborators

  • peersyst