diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/sessions.controller.ts | 43 | ||||
-rw-r--r-- | server/controllers/user.controller.ts | 0 | ||||
-rw-r--r-- | server/controllers/users.controller.ts | 50 | ||||
-rw-r--r-- | server/database/cli_config.ts | 8 | ||||
-rw-r--r-- | server/database/migrations/1637028716848-AddUser.ts | 2 | ||||
-rw-r--r-- | server/dto/create_user.dto.ts | 5 | ||||
-rw-r--r-- | server/entities/user.entity.ts | 18 | ||||
-rw-r--r-- | server/main.ts | 8 | ||||
-rw-r--r-- | server/modules/users.module.ts | 4 | ||||
-rw-r--r-- | server/providers/services/users.service.ts | 12 |
10 files changed, 120 insertions, 30 deletions
diff --git a/server/controllers/sessions.controller.ts b/server/controllers/sessions.controller.ts index 884ad3c..3b179ad 100644 --- a/server/controllers/sessions.controller.ts +++ b/server/controllers/sessions.controller.ts @@ -1,7 +1,17 @@ -import { Body, Controller, Post, Res } from '@nestjs/common'; -import { UsersService } from 'server/providers/services/users.service'; -import { SignInDto } from '../dto/sign_in.dto'; +import { + Body, + Controller, + HttpException, + HttpStatus, + Post, + Res, +} from '@nestjs/common'; import { Response } from 'express'; +import * as jwt from 'jsonwebtoken'; +import { UsersService } from 'server/providers/services/users.service'; +import { SignInDto } from 'server/dto/sign_in.dto'; + + // this is kind of a misnomer because we are doing token based auth // instead of session based auth @Controller() @@ -9,19 +19,30 @@ export class SessionsController { constructor(private usersService: UsersService) {} @Post('/sign_in') - async signIn(@Body() body: SignInDto, @Res() res: Response) { - console.log("DO I GET RAN?") - const verified = await this.usersService.verify( + async signIn( + @Body() body: SignInDto, + @Res({ passthrough: true }) res: Response, + ) { + const { verified, user } = await this.usersService.verify( body.username, body.password, ); if (!verified) { - res.status(400); - console.log("here too??") - res.json({ message: 'Invalid email or password' }); - return; + throw new HttpException( + 'Invalid email or password.', + HttpStatus.BAD_REQUEST, + ); } - res.json({ success: true }); + // Write JWT to cookie and send with response. + const token = jwt.sign( + { + user_id: user.id, + }, + process.env.ENCRYPTION_KEY, + { expiresIn: '1h' }, + ); + res.cookie('_token', token); + return { token }; } } diff --git a/server/controllers/user.controller.ts b/server/controllers/user.controller.ts deleted file mode 100644 index e69de29..0000000 --- a/server/controllers/user.controller.ts +++ /dev/null diff --git a/server/controllers/users.controller.ts b/server/controllers/users.controller.ts new file mode 100644 index 0000000..773b110 --- /dev/null +++ b/server/controllers/users.controller.ts @@ -0,0 +1,50 @@ +import { + Body, + Controller, + HttpException, + HttpStatus, + Post, + Res, +} from '@nestjs/common'; +import bcrypt from 'bcrypt'; +import { Response } from 'express'; +import * as jwt from 'jsonwebtoken'; +import { CreateUserDto } from 'server/dto/create_user.dto'; +import { User } from 'server/entities/user.entity'; +import { UsersService } from 'server/providers/services/users.service'; + +@Controller() +export class UsersController { + constructor(private usersService: UsersService) {} + + @Post('/users') + async create( + @Body() userPayload: CreateUserDto, + @Res({ passthrough: true }) res: Response, + ) { + const newUser = new User(); + newUser.email = userPayload.email; + newUser.name = userPayload.name; + newUser.password_hash = await bcrypt.hash(userPayload.password, 10); + + try { + const user = await this.usersService.create(newUser); + // assume signup and write cookie + // Write JWT to cookie and send with response. + const token = jwt.sign( + { + user_id: user.id, + }, + process.env.ENCRYPTION_KEY, + { expiresIn: '1h' }, + ); + res.cookie('_token', token); + return { user, token }; + } catch (e) { + throw new HttpException( + `User creation failed. ${e.message}`, + HttpStatus.BAD_REQUEST, + ); + } + } +} diff --git a/server/database/cli_config.ts b/server/database/cli_config.ts index ca7104a..e75cce8 100644 --- a/server/database/cli_config.ts +++ b/server/database/cli_config.ts @@ -7,16 +7,16 @@ export = process.env.NODE_ENV === 'development' port: 5432, database: process.env.DATABASE_URL, autoLoadEntities: true, - migrations: ['src/database/migrations/*.ts'], + migrations: ['server/database/migrations/*.ts'], cli: { - migrationsDir: 'src/database/migrations', + migrationsDir: 'server/database/migrations', }, } : { url: process.env.DATABASE_URL, ssl: { rejectUnauthorized: true }, - migrations: ['src/database/migrations/*.ts'], + migrations: ['server/database/migrations/*.ts'], cli: { - migrationsDir: 'src/database/migrations', + migrationsDir: 'server/database/migrations', }, }; diff --git a/server/database/migrations/1637028716848-AddUser.ts b/server/database/migrations/1637028716848-AddUser.ts index 6241637..2689d49 100644 --- a/server/database/migrations/1637028716848-AddUser.ts +++ b/server/database/migrations/1637028716848-AddUser.ts @@ -10,6 +10,7 @@ export class AddUser1637028716848 implements MigrationInterface { name: 'id', type: 'int', isPrimary: true, + isGenerated: true, }, { name: 'name', @@ -25,6 +26,7 @@ export class AddUser1637028716848 implements MigrationInterface { name: 'email', type: 'text', isNullable: false, + isUnique: true, }, ], }), diff --git a/server/dto/create_user.dto.ts b/server/dto/create_user.dto.ts new file mode 100644 index 0000000..cf87fed --- /dev/null +++ b/server/dto/create_user.dto.ts @@ -0,0 +1,5 @@ +export class CreateUserDto { + name: string; + email: string; + password: string; +} diff --git a/server/entities/user.entity.ts b/server/entities/user.entity.ts index df39f3f..0bc02a7 100644 --- a/server/entities/user.entity.ts +++ b/server/entities/user.entity.ts @@ -2,15 +2,15 @@ import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; @Entity() export class User { - @PrimaryGeneratedColumn() - id: number; + @PrimaryGeneratedColumn() + id: number; - @Column() - email: string; + @Column({ unique: true, nullable: false }) + email: string; - @Column() - name: string; + @Column({ nullable: false }) + name: string; - @Column() - password_hash: string; -}
\ No newline at end of file + @Column({ nullable: false }) + password_hash: string; +} diff --git a/server/main.ts b/server/main.ts index 2ed7d94..486bb86 100644 --- a/server/main.ts +++ b/server/main.ts @@ -2,9 +2,9 @@ import './env'; import * as fs from 'fs'; import { NestFactory } from '@nestjs/core'; import { join } from 'path'; -import * as morgan from 'morgan'; -import { AppModule } from './app.module'; import { NestExpressApplication } from '@nestjs/platform-express'; +import * as cookieParser from 'cookie-parser'; +import { AppModule } from './app.module'; async function bootstrap() { let httpsOptions; @@ -16,8 +16,10 @@ async function bootstrap() { } const app = await NestFactory.create<NestExpressApplication>(AppModule, { httpsOptions, + logger: ['verbose'], }); - app.use(morgan('tiny')); + + app.use(cookieParser()); app.useStaticAssets(join(__dirname, '..', 'static')); app.setBaseViewsDir(join(__dirname, '../', 'views')); app.setViewEngine('hbs'); diff --git a/server/modules/users.module.ts b/server/modules/users.module.ts index 1c88c75..a59e24d 100644 --- a/server/modules/users.module.ts +++ b/server/modules/users.module.ts @@ -2,10 +2,12 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { User } from 'server/entities/user.entity'; import { SessionsController } from '../controllers/sessions.controller'; +import { UsersController } from 'server/controllers/users.controller'; import { UsersService } from '../providers/services/users.service'; + @Module({ imports: [TypeOrmModule.forFeature([User])], - controllers: [SessionsController], + controllers: [SessionsController, UsersController], providers: [UsersService], }) export class UsersModule {} diff --git a/server/providers/services/users.service.ts b/server/providers/services/users.service.ts index efeef1d..5a2a1fb 100644 --- a/server/providers/services/users.service.ts +++ b/server/providers/services/users.service.ts @@ -19,9 +19,17 @@ export class UsersService { return this.usersRespository.findOne(id); } + create(user: User) { + return this.usersRespository.save(user); + } + async verify(email: string, password: string) { const user = await this.usersRespository.findOne({ email }); - if (!user) return false; - return bcrypt.compare(password, user.password_hash); + if (!user) return { verified: false, user: null }; + const verified: boolean = await bcrypt.compare( + password, + user.password_hash, + ); + return { verified, user }; } } |