diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/app.controller.spec.ts | 22 | ||||
-rw-r--r-- | server/app.controller.ts | 8 | ||||
-rw-r--r-- | server/app.module.ts | 13 | ||||
-rw-r--r-- | server/app.service.ts | 8 | ||||
-rw-r--r-- | server/controllers/sessions.controller.ts | 27 | ||||
-rw-r--r-- | server/controllers/user.controller.ts | 0 | ||||
-rw-r--r-- | server/database/cli_config.ts | 22 | ||||
-rw-r--r-- | server/database/config.ts | 16 | ||||
-rw-r--r-- | server/database/migrations/1637028716848-AddUser.ts | 37 | ||||
-rw-r--r-- | server/dto/sign_in.dto.ts | 4 | ||||
-rw-r--r-- | server/entities/user.entity.ts | 16 | ||||
-rw-r--r-- | server/env.ts | 2 | ||||
-rw-r--r-- | server/main.ts | 26 | ||||
-rw-r--r-- | server/modules/users.module.ts | 11 | ||||
-rw-r--r-- | server/providers/services/users.service.ts | 27 |
15 files changed, 239 insertions, 0 deletions
diff --git a/server/app.controller.spec.ts b/server/app.controller.spec.ts new file mode 100644 index 0000000..d22f389 --- /dev/null +++ b/server/app.controller.spec.ts @@ -0,0 +1,22 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AppController } from './app.controller'; +import { AppService } from './app.service'; + +describe('AppController', () => { + let appController: AppController; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + controllers: [AppController], + providers: [AppService], + }).compile(); + + appController = app.get<AppController>(AppController); + }); + + describe('root', () => { + it('should return "Hello World!"', () => { + expect(appController.getHello()).toBe('Hello World!'); + }); + }); +}); diff --git a/server/app.controller.ts b/server/app.controller.ts new file mode 100644 index 0000000..a6bcf58 --- /dev/null +++ b/server/app.controller.ts @@ -0,0 +1,8 @@ +import { Controller, Get, Render } from '@nestjs/common'; + +@Controller() +export class AppController { + @Get() + @Render('index') + index() {} +} diff --git a/server/app.module.ts b/server/app.module.ts new file mode 100644 index 0000000..4e4f8d1 --- /dev/null +++ b/server/app.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AppController } from './app.controller'; +import { AppService } from './app.service'; +import { config } from './database/config'; +import { UsersModule } from './modules/users.module'; + +@Module({ + imports: [TypeOrmModule.forRoot(config), UsersModule], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} diff --git a/server/app.service.ts b/server/app.service.ts new file mode 100644 index 0000000..927d7cc --- /dev/null +++ b/server/app.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class AppService { + getHello(): string { + return 'Hello World!'; + } +} diff --git a/server/controllers/sessions.controller.ts b/server/controllers/sessions.controller.ts new file mode 100644 index 0000000..884ad3c --- /dev/null +++ b/server/controllers/sessions.controller.ts @@ -0,0 +1,27 @@ +import { Body, Controller, Post, Res } from '@nestjs/common'; +import { UsersService } from 'server/providers/services/users.service'; +import { SignInDto } from '../dto/sign_in.dto'; +import { Response } from 'express'; +// this is kind of a misnomer because we are doing token based auth +// instead of session based auth +@Controller() +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( + body.username, + body.password, + ); + + if (!verified) { + res.status(400); + console.log("here too??") + res.json({ message: 'Invalid email or password' }); + return; + } + res.json({ success: true }); + } +} diff --git a/server/controllers/user.controller.ts b/server/controllers/user.controller.ts new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/server/controllers/user.controller.ts diff --git a/server/database/cli_config.ts b/server/database/cli_config.ts new file mode 100644 index 0000000..ca7104a --- /dev/null +++ b/server/database/cli_config.ts @@ -0,0 +1,22 @@ +import '../env'; + +export = process.env.NODE_ENV === 'development' + ? { + type: 'postgres', + host: 'localhost', + port: 5432, + database: process.env.DATABASE_URL, + autoLoadEntities: true, + migrations: ['src/database/migrations/*.ts'], + cli: { + migrationsDir: 'src/database/migrations', + }, + } + : { + url: process.env.DATABASE_URL, + ssl: { rejectUnauthorized: true }, + migrations: ['src/database/migrations/*.ts'], + cli: { + migrationsDir: 'src/database/migrations', + }, + }; diff --git a/server/database/config.ts b/server/database/config.ts new file mode 100644 index 0000000..80f479a --- /dev/null +++ b/server/database/config.ts @@ -0,0 +1,16 @@ +import { TypeOrmModuleOptions } from '@nestjs/typeorm'; +import '../env'; + +export const config: TypeOrmModuleOptions = + process.env.NODE_ENV === 'development' + ? { + type: 'postgres', + host: 'localhost', + port: 5432, + database: process.env.DATABASE_URL, + autoLoadEntities: true, + } + : { + url: process.env.DATABASE_URL, + ssl: { rejectUnauthorized: true }, + }; diff --git a/server/database/migrations/1637028716848-AddUser.ts b/server/database/migrations/1637028716848-AddUser.ts new file mode 100644 index 0000000..6241637 --- /dev/null +++ b/server/database/migrations/1637028716848-AddUser.ts @@ -0,0 +1,37 @@ +import { MigrationInterface, QueryRunner, Table } from 'typeorm'; + +export class AddUser1637028716848 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.createTable( + new Table({ + name: 'user', + columns: [ + { + name: 'id', + type: 'int', + isPrimary: true, + }, + { + name: 'name', + type: 'text', + isNullable: false, + }, + { + name: 'password_hash', + type: 'text', + isNullable: false, + }, + { + name: 'email', + type: 'text', + isNullable: false, + }, + ], + }), + ); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.dropTable('user'); + } +} diff --git a/server/dto/sign_in.dto.ts b/server/dto/sign_in.dto.ts new file mode 100644 index 0000000..f480c43 --- /dev/null +++ b/server/dto/sign_in.dto.ts @@ -0,0 +1,4 @@ +export class SignInDto { + username: string; + password: string; +} diff --git a/server/entities/user.entity.ts b/server/entities/user.entity.ts new file mode 100644 index 0000000..df39f3f --- /dev/null +++ b/server/entities/user.entity.ts @@ -0,0 +1,16 @@ +import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; + +@Entity() +export class User { + @PrimaryGeneratedColumn() + id: number; + + @Column() + email: string; + + @Column() + name: string; + + @Column() + password_hash: string; +}
\ No newline at end of file diff --git a/server/env.ts b/server/env.ts new file mode 100644 index 0000000..37dc70c --- /dev/null +++ b/server/env.ts @@ -0,0 +1,2 @@ +import { config } from 'dotenv'; +config(); diff --git a/server/main.ts b/server/main.ts new file mode 100644 index 0000000..2ed7d94 --- /dev/null +++ b/server/main.ts @@ -0,0 +1,26 @@ +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'; + +async function bootstrap() { + let httpsOptions; + if (process.env.NODE_ENV === 'development') { + httpsOptions = { + key: fs.readFileSync('./private-key.pem'), + cert: fs.readFileSync('./public-cert.pem'), + }; + } + const app = await NestFactory.create<NestExpressApplication>(AppModule, { + httpsOptions, + }); + app.use(morgan('tiny')); + app.useStaticAssets(join(__dirname, '..', 'static')); + app.setBaseViewsDir(join(__dirname, '../', 'views')); + app.setViewEngine('hbs'); + await app.listen(process.env.PORT); +} +bootstrap(); diff --git a/server/modules/users.module.ts b/server/modules/users.module.ts new file mode 100644 index 0000000..1c88c75 --- /dev/null +++ b/server/modules/users.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { User } from 'server/entities/user.entity'; +import { SessionsController } from '../controllers/sessions.controller'; +import { UsersService } from '../providers/services/users.service'; +@Module({ + imports: [TypeOrmModule.forFeature([User])], + controllers: [SessionsController], + providers: [UsersService], +}) +export class UsersModule {} diff --git a/server/providers/services/users.service.ts b/server/providers/services/users.service.ts new file mode 100644 index 0000000..efeef1d --- /dev/null +++ b/server/providers/services/users.service.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import bcrypt from 'bcrypt'; +import { User } from '../../entities/user.entity'; + +@Injectable() +export class UsersService { + constructor( + @InjectRepository(User) + private usersRespository: Repository<User>, + ) {} + + findBy(options: Record<string, any>) { + return this.usersRespository.findOne(options); + } + + find(id: number) { + return this.usersRespository.findOne(id); + } + + async verify(email: string, password: string) { + const user = await this.usersRespository.findOne({ email }); + if (!user) return false; + return bcrypt.compare(password, user.password_hash); + } +} |