Create resource
nest g resource [name_resource] [--no-spec]
file .env
PORT=8081
MONGODB_URI=mongodb://root:123456@localhost:27017/quyenlee?authSource=admin
JWT_SECRET_KEY=aa4f8e2b-0d8a-49d1-be30-f532d78fbb56
JWT_ACCESS_TOKEN_EXPIRES_IN=1000d
file .env.local
MAILDEV_INCOMING_USER=
MAILDEV_INCOMING_PASS=
Change dynamic port get from .env
in main.ts
import { ConfigService } from '@nestjs/config';
const configService = app.get(ConfigService);
const port = configService.get<number>('PORT');
await app.listen(port);
Connect mongodb
import { ConfigModule, ConfigService } from '@nestjs/config';
import { MongooseModule } from '@nestjs/mongoose';
@Module({
imports: [
UsersModule,
ConfigModule.forRoot({ isGlobal: true, envFilePath: ['.env', '.env.local'] }), // TODO: Khai bao env file path app read
MongooseModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
uri: configService.get<string>('MONGODB_URI'),
}),
inject: [ConfigService],
}),
],
controllers: [AppController],
providers: [AppService],
})
schemas (in mongodb) is entities (SQL)
A simple schema
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';
export type UserDocument = HydratedDocument<User>;
@Schema()
export class User {
@Prop()
name: string;
@Prop()
age: number;
@Prop({ default: UserRoles.USER })
role: UserRoles;
@Prop({ default: AccountType.NORMAL })
accountType: AccountType;
}
export const UserSchema = SchemaFactory.createForClass(User);
import { JwtModule } from '@nestjs/jwt';
import { ConfigModule, ConfigService } from '@nestjs/config';
@Module({
imports: [
UsersModule,
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
global: true,
secretOrPrivateKey: configService.get<string>('JWT_SECRET_KEY'),
signOptions: {
expiresIn: configService.get<string>('JWT_ACCESS_TOKEN_EXPIRES_IN'),
},
}),
inject: [ConfigService],
}),
],
controllers: [AuthController],
providers: [AuthService],
exports: [AuthService],
})
Should use Passport.
npm i --save-exact @nestjs/[email protected] [email protected] [email protected]
npm i --save-dev @types/passport-local
npm i --save-exact @nestjs/[email protected] [email protected]
npm i --save-dev @types/passport-jwt
Each guard
have strategy: Ex:
JwtAuthGuard
haveJwtStrategy
LocalAuthGuard
haveLocalStrategy
In controller
when use @UseGuards(LocalAuthGuard | JwtAuthGuard)
the request return data user by function validate
in LocalStrategy | JwtStrategy
npm i --save-exact @nestjs-modules/[email protected] [email protected] [email protected]
npm i --save-dev @types/nodemailer
change config in nest-cli.json
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true,
"assets": ["mail/templates/**/*"] // complie template .hbs
},
"watchAssets": true
}
config mail module in app.module.ts
MailerModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
transport: {
host: 'smtp.gmail.com',
port: 465,
// ignoreTLS: true,
secure: true,
auth: {
user: configService.get<string>('MAILDEV_INCOMING_USER'),
pass: configService.get<string>('MAILDEV_INCOMING_PASS'),
},
},
defaults: {
from: '"No Reply" <no-reply@localhost>',
},
// preview: true,
template: {
dir: process.cwd() + '/src/mail/templates/',
adapter: new HandlebarsAdapter(), // or new PugAdapter() or new EjsAdapter()
options: {
strict: true,
},
},
}),
inject: [ConfigService],
}),
And send email when register acount
this.mailerService
.sendMail({
to: newUser.email,
subject: 'Activate your account',
template: 'register', //where: src/mail/templates/register.hbs
context: {
name: newUser.name || newUser.email,
activationCode: codeId,
},
})
.then(() => {})
.catch((e) => {
console.log('co loi roi', e);
});