summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/controllers/sessions.controller.ts43
-rw-r--r--server/controllers/user.controller.ts0
-rw-r--r--server/controllers/users.controller.ts50
-rw-r--r--server/database/cli_config.ts8
-rw-r--r--server/database/migrations/1637028716848-AddUser.ts2
-rw-r--r--server/dto/create_user.dto.ts5
-rw-r--r--server/entities/user.entity.ts18
-rw-r--r--server/main.ts8
-rw-r--r--server/modules/users.module.ts4
-rw-r--r--server/providers/services/users.service.ts12
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 };
}
}