start mailing service, and public form output
This commit is contained in:
parent
93f63f7421
commit
70859f6871
@ -33,6 +33,7 @@
|
||||
"bcrypt": "^3.0.6",
|
||||
"class-transformer": "^0.2.3",
|
||||
"class-validator": "^0.9.1",
|
||||
"handlebars": "^4.1.2",
|
||||
"mongoose": "^5.6.7",
|
||||
"nestjs-typegoose": "^5.2.1",
|
||||
"passport": "^0.4.0",
|
||||
|
||||
@ -8,6 +8,7 @@ import { AppService } from './app.service';
|
||||
import { UserModule } from "./user/user.module"
|
||||
import { FormModule } from "./form/form.module"
|
||||
import { AuthModule } from './auth/auth.module';
|
||||
import { MailModule } from "./mail/mail.module"
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@ -19,6 +20,7 @@ import { AuthModule } from './auth/auth.module';
|
||||
UserModule,
|
||||
FormModule,
|
||||
AuthModule,
|
||||
MailModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
|
||||
@ -5,11 +5,13 @@ import { jwtConstants } from "./constants"
|
||||
import { JwtModule } from "@nestjs/jwt"
|
||||
import controllers from './auth.controllers'
|
||||
import providers from './auth.providers'
|
||||
import { MailModule } from "../mail/mail.module"
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
UserModule,
|
||||
PassportModule,
|
||||
MailModule,
|
||||
JwtModule.register({
|
||||
secret: jwtConstants.secret,
|
||||
signOptions: { expiresIn: '12h' },
|
||||
|
||||
@ -3,6 +3,7 @@ import { PasswordService } from "./services/password.service"
|
||||
import { PasswordStrategy } from "./strategies/password.strategy"
|
||||
import { JwtStrategy } from "./strategies/jwt.strategy"
|
||||
import { JwtRefreshStrategy } from "./strategies/jwt.refresh.strategy"
|
||||
import { RegisterService } from "./services/register.service"
|
||||
|
||||
export default [
|
||||
AuthService,
|
||||
@ -10,4 +11,5 @@ export default [
|
||||
PasswordStrategy,
|
||||
JwtStrategy,
|
||||
JwtRefreshStrategy,
|
||||
RegisterService,
|
||||
]
|
||||
|
||||
@ -1,21 +1,18 @@
|
||||
import { Controller, Request, Post, UseGuards } from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { Controller, Post, Body } from '@nestjs/common';
|
||||
import { AuthService } from "../services/auth.service"
|
||||
import { AuthJwtDto } from "../dto/auth.jwt.dto"
|
||||
import {ApiBearerAuth, ApiImplicitBody, ApiImplicitQuery, ApiResponse, ApiUseTags} from "@nestjs/swagger"
|
||||
import { ApiBadRequestResponse, ApiCreatedResponse, ApiUseTags } from "@nestjs/swagger"
|
||||
import { RegisterDto } from "../dto/register.dto"
|
||||
import {RegisterService} from "../services/register.service"
|
||||
|
||||
@ApiUseTags('authentication')
|
||||
@Controller('auth')
|
||||
export class RegisterController {
|
||||
constructor(private readonly authService: AuthService) {}
|
||||
constructor(private readonly registerService: RegisterService) {}
|
||||
|
||||
@ApiResponse({ status: 201, description: 'Successful registration.', type: AuthJwtDto})
|
||||
@ApiImplicitQuery({name: 'email', type: String})
|
||||
@ApiImplicitQuery({name: 'username', type: String})
|
||||
@ApiImplicitQuery({name: 'password', type: String})
|
||||
@ApiCreatedResponse({ description: 'Successful registration.'})
|
||||
@ApiBadRequestResponse({})
|
||||
@Post('register')
|
||||
async register(@Request() req): Promise<AuthJwtDto> {
|
||||
// TODO
|
||||
return null
|
||||
async register(@Body() params: RegisterDto): Promise<void> {
|
||||
await this.registerService.register(params.username, params.email, params.password)
|
||||
}
|
||||
}
|
||||
|
||||
12
api/src/auth/dto/register.dto.ts
Normal file
12
api/src/auth/dto/register.dto.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { ApiModelProperty } from "@nestjs/swagger"
|
||||
|
||||
export class RegisterDto {
|
||||
@ApiModelProperty()
|
||||
readonly username: string;
|
||||
|
||||
@ApiModelProperty()
|
||||
readonly password: string;
|
||||
|
||||
@ApiModelProperty()
|
||||
readonly email: string;
|
||||
}
|
||||
21
api/src/auth/services/register.service.ts
Normal file
21
api/src/auth/services/register.service.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { Injectable } from "@nestjs/common"
|
||||
import { MailService } from "../../mail/services/mail.service"
|
||||
|
||||
@Injectable()
|
||||
export class RegisterService {
|
||||
constructor(private readonly mailService: MailService) {}
|
||||
|
||||
async register (username: string, email: string, password: string): Promise<void> {
|
||||
// TODO actually create user
|
||||
|
||||
await this.mailService.sendEmail(
|
||||
{
|
||||
template: 'auth/register.hbs',
|
||||
to: email
|
||||
},
|
||||
{
|
||||
confirm: 'some url'
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,7 @@ import { PassportStrategy } from '@nestjs/passport';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { jwtConstants } from '../constants';
|
||||
import { AuthService } from "../services/auth.service"
|
||||
import {AuthUser} from "../interfaces/auth.user.interface"
|
||||
import { AuthUser } from "../interfaces/auth.user.interface"
|
||||
|
||||
@Injectable()
|
||||
export class JwtRefreshStrategy extends PassportStrategy(Strategy, 'jwt.refresh') {
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import {Controller, Request, Get, Post, Put, Delete, UseGuards, Param} from '@nestjs/common';
|
||||
import {Controller, Request, Get, Post, Put, Delete, UseGuards, Param, NotImplementedException} from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { ApiUseTags } from "@nestjs/swagger"
|
||||
import { ApiBearerAuth, ApiImplicitQuery, ApiResponse, ApiUseTags } from "@nestjs/swagger"
|
||||
import { FormService } from "../services/form.service"
|
||||
import {Form} from "../models/form.model"
|
||||
import { FormDto } from "../dto/form.dto"
|
||||
|
||||
@ApiUseTags('forms')
|
||||
@ApiBearerAuth()
|
||||
@Controller('forms')
|
||||
export class FormController {
|
||||
constructor(private readonly formService: FormService) {}
|
||||
@ -12,28 +13,31 @@ export class FormController {
|
||||
@Get()
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async list(@Request() req): Promise<any> {
|
||||
return true;
|
||||
throw new NotImplementedException()
|
||||
}
|
||||
@Post()
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async create(@Request() req): Promise<Form> {
|
||||
return null;
|
||||
async create(@Request() req): Promise<FormDto> {
|
||||
throw new NotImplementedException()
|
||||
}
|
||||
|
||||
@ApiResponse({ status: 200, description: 'Form Object', type: FormDto})
|
||||
@ApiImplicitQuery({name: 'id', type: String})
|
||||
@Get(':id')
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async read(@Param('id') id): Promise<Form> {
|
||||
return this.formService.findById(id);
|
||||
async read(@Param('id') id): Promise<FormDto> {
|
||||
return new FormDto(await this.formService.findById(id));
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async update(@Param('id') id, @Request() req): Promise<Form> {
|
||||
return this.formService.findById(id);
|
||||
async update(@Param('id') id, @Request() req): Promise<FormDto> {
|
||||
throw new NotImplementedException()
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async delete(@Param('id') id): Promise<void> {
|
||||
throw new NotImplementedException()
|
||||
}
|
||||
}
|
||||
|
||||
24
api/src/form/controllers/public.controller.ts
Normal file
24
api/src/form/controllers/public.controller.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Controller, Get, Param, NotFoundException } from '@nestjs/common';
|
||||
import { ApiImplicitQuery, ApiResponse, ApiUseTags } from "@nestjs/swagger"
|
||||
import { FormService } from "../services/form.service"
|
||||
import { Form } from "../models/form.model"
|
||||
import { PublicFormDto } from "../dto/public.form.dto"
|
||||
|
||||
@ApiUseTags('forms')
|
||||
@Controller('public')
|
||||
export class PublicController {
|
||||
constructor(private readonly formService: FormService) {}
|
||||
|
||||
@ApiResponse({ status: 200, description: 'Form Object', type: PublicFormDto})
|
||||
@ApiImplicitQuery({name: 'id', type: String})
|
||||
@Get(':id')
|
||||
async read(@Param('id') id): Promise<PublicFormDto> {
|
||||
const form:Form = await this.formService.findById(id)
|
||||
|
||||
if (!form.isLive) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return new PublicFormDto(form);
|
||||
}
|
||||
}
|
||||
17
api/src/form/dto/form.dto.ts
Normal file
17
api/src/form/dto/form.dto.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { ApiModelProperty } from '@nestjs/swagger';
|
||||
import { Form } from "../models/form.model"
|
||||
|
||||
export class FormDto {
|
||||
@ApiModelProperty()
|
||||
id: string;
|
||||
|
||||
@ApiModelProperty()
|
||||
title: string;
|
||||
|
||||
fields: [];
|
||||
|
||||
constructor(partial: Partial<Form>) {
|
||||
this.id = partial._id.toString();
|
||||
this.title = partial.title
|
||||
}
|
||||
}
|
||||
17
api/src/form/dto/public.form.dto.ts
Normal file
17
api/src/form/dto/public.form.dto.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { ApiModelProperty } from '@nestjs/swagger';
|
||||
import { Form } from "../models/form.model"
|
||||
|
||||
export class PublicFormDto {
|
||||
@ApiModelProperty()
|
||||
id: string;
|
||||
|
||||
@ApiModelProperty()
|
||||
title: string;
|
||||
|
||||
fields: [];
|
||||
|
||||
constructor(partial: Partial<Form>) {
|
||||
this.id = partial._id.toString();
|
||||
this.title = partial.title
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
import { FormController } from "./controllers/form.controller"
|
||||
import { PublicController } from "./controllers/public.controller"
|
||||
|
||||
export default [
|
||||
FormController,
|
||||
PublicController,
|
||||
]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {prop, Ref, Typegoose} from "typegoose"
|
||||
import {arrayProp, prop, Ref, Typegoose} from "typegoose"
|
||||
import {Analytics} from "./embedded/analytics"
|
||||
import {Field} from "./embedded/field"
|
||||
import {StartPage} from "./embedded/start.page"
|
||||
@ -8,12 +8,18 @@ import {RespondentNotifications} from "./embedded/respondent.notifications"
|
||||
import {Design} from "./embedded/design"
|
||||
import {User} from "../../user/models/user.model"
|
||||
|
||||
export class Form extends Typegoose{
|
||||
export class Form extends Typegoose {
|
||||
readonly _id: any;
|
||||
|
||||
@prop({
|
||||
trim: true,
|
||||
required: 'Form Title cannot be blank'
|
||||
})
|
||||
readonly firstName: string;
|
||||
readonly title: string;
|
||||
|
||||
readonly created: any;
|
||||
|
||||
readonly lastModified: any;
|
||||
|
||||
@prop({
|
||||
enum: ['en', 'fr', 'es', 'it', 'de'],
|
||||
@ -25,7 +31,8 @@ export class Form extends Typegoose{
|
||||
@prop()
|
||||
readonly analytics: Analytics;
|
||||
|
||||
@prop({
|
||||
@arrayProp({
|
||||
items: Field,
|
||||
default: []
|
||||
})
|
||||
readonly form_fields: Field[];
|
||||
|
||||
12
api/src/mail/dto/options.dto.ts
Normal file
12
api/src/mail/dto/options.dto.ts
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
export class OptionsDto {
|
||||
template: string;
|
||||
|
||||
language?: string;
|
||||
|
||||
to: string;
|
||||
|
||||
cc?: string[];
|
||||
|
||||
bcc?: string[];
|
||||
}
|
||||
5
api/src/mail/mail.exports.ts
Normal file
5
api/src/mail/mail.exports.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { MailService } from "./services/mail.service"
|
||||
|
||||
export default [
|
||||
MailService
|
||||
]
|
||||
10
api/src/mail/mail.module.ts
Normal file
10
api/src/mail/mail.module.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import providers from './mail.providers'
|
||||
import exportList from './mail.exports'
|
||||
|
||||
@Module({
|
||||
imports: [],
|
||||
providers,
|
||||
exports: exportList,
|
||||
})
|
||||
export class MailModule {}
|
||||
5
api/src/mail/mail.providers.ts
Normal file
5
api/src/mail/mail.providers.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { MailService } from "./services/mail.service"
|
||||
|
||||
export default [
|
||||
MailService
|
||||
]
|
||||
10
api/src/mail/services/mail.service.ts
Normal file
10
api/src/mail/services/mail.service.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { OptionsDto } from "../dto/options.dto"
|
||||
|
||||
@Injectable()
|
||||
export class MailService {
|
||||
// TODO
|
||||
async sendEmail(options:OptionsDto, placeholders:any): Promise<boolean> {
|
||||
return false
|
||||
}
|
||||
}
|
||||
6
api/src/mail/views/en/auth/recover.hbs
Normal file
6
api/src/mail/views/en/auth/recover.hbs
Normal file
@ -0,0 +1,6 @@
|
||||
Hi,
|
||||
|
||||
if you have not requested a new password you can ignore this email. To set a new password for your account
|
||||
just follow this link: {{ recover }}
|
||||
|
||||
See you soon
|
||||
5
api/src/mail/views/en/auth/register.hbs
Normal file
5
api/src/mail/views/en/auth/register.hbs
Normal file
@ -0,0 +1,5 @@
|
||||
Welcome to OhMyForm!
|
||||
|
||||
please confirm your account by following the following link: {{ confirm }}
|
||||
|
||||
enjoy!
|
||||
@ -15,7 +15,7 @@ async function bootstrap() {
|
||||
transform: true,
|
||||
}));
|
||||
|
||||
// app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)))
|
||||
app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)))
|
||||
|
||||
const options = new DocumentBuilder()
|
||||
.setTitle('OhMyForm')
|
||||
|
||||
50
api/src/user/controllers/user.controller.ts
Normal file
50
api/src/user/controllers/user.controller.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import {Controller, Request, Get, Post, Put, Delete, UseGuards, Param, NotImplementedException} from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { ApiBearerAuth, ApiImplicitQuery, ApiResponse, ApiUseTags } from "@nestjs/swagger"
|
||||
import { UserService } from "../services/user.service"
|
||||
import { UserDto } from "../dto/user.dto"
|
||||
|
||||
@ApiUseTags('users')
|
||||
@ApiBearerAuth()
|
||||
@Controller('users')
|
||||
export class UserController {
|
||||
constructor(private readonly userService: UserService) {}
|
||||
|
||||
@Get()
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async list(@Request() req): Promise<any> {
|
||||
throw new NotImplementedException()
|
||||
}
|
||||
|
||||
@ApiResponse({ status: 200, description: 'User Object', type: UserDto})
|
||||
@Post()
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async create(@Request() req): Promise<UserDto> {
|
||||
throw new NotImplementedException()
|
||||
}
|
||||
|
||||
@ApiResponse({ status: 200, description: 'User Object', type: UserDto})
|
||||
@ApiImplicitQuery({name: 'id', type: String})
|
||||
@Get(':id')
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async read(@Param('id') id): Promise<UserDto> {
|
||||
return new UserDto(await this.userService.findById(id));
|
||||
}
|
||||
|
||||
@ApiResponse({ status: 200, description: 'User Object', type: UserDto})
|
||||
@ApiImplicitQuery({name: 'id', type: String})
|
||||
@Put(':id')
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async update(@Param('id') id, @Request() req): Promise<UserDto> {
|
||||
throw new NotImplementedException()
|
||||
}
|
||||
|
||||
|
||||
@ApiResponse({ status: 200, description: 'User Object', type: UserDto})
|
||||
@ApiImplicitQuery({name: 'id', type: String})
|
||||
@Delete(':id')
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
async delete(@Param('id') id): Promise<void> {
|
||||
throw new NotImplementedException()
|
||||
}
|
||||
}
|
||||
15
api/src/user/dto/user.dto.ts
Normal file
15
api/src/user/dto/user.dto.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { ApiModelProperty } from '@nestjs/swagger';
|
||||
import {User} from "../models/user.model"
|
||||
|
||||
export class UserDto {
|
||||
@ApiModelProperty()
|
||||
id: string;
|
||||
|
||||
@ApiModelProperty()
|
||||
username: string;
|
||||
|
||||
constructor(partial: Partial<User>) {
|
||||
this.id = partial._id.toString();
|
||||
this.username = partial.username
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ import {Injectable, NotFoundException} from '@nestjs/common';
|
||||
import { InjectModel } from 'nestjs-typegoose';
|
||||
import { ModelType } from 'typegoose';
|
||||
import { User } from "../models/user.model"
|
||||
import {Form} from "../../form/models/form.model"
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
@ -23,4 +24,8 @@ export class UserService {
|
||||
|
||||
return results[0]
|
||||
}
|
||||
|
||||
async findById(id: string): Promise<User> {
|
||||
return await this.userModel.findById(id).exec()
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
import { UserController } from "./controllers/user.controller"
|
||||
|
||||
export default [
|
||||
UserController,
|
||||
]
|
||||
@ -3,11 +3,13 @@ import { TypegooseModule } from 'nestjs-typegoose';
|
||||
import providers from './user.providers'
|
||||
import exportList from './user.exports'
|
||||
import { User } from "./models/user.model"
|
||||
import controllers from './user.controllers'
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypegooseModule.forFeature([User]),
|
||||
],
|
||||
controllers,
|
||||
providers,
|
||||
exports: exportList,
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user