feat(api): setup nestjs

This commit is contained in:
Julian Tölle 2020-01-25 22:19:14 +01:00
commit db62d5d908
25 changed files with 10115 additions and 0 deletions

15
src/app.module.ts Normal file
View file

@ -0,0 +1,15 @@
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { AuthenticationModule } from "./authentication/authentication.module";
import { DatabaseModule } from "./database/database.module";
import { ConnectionsModule } from "./connections/connections.module";
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
DatabaseModule,
AuthenticationModule,
ConnectionsModule
]
})
export class AppModule {}

View file

@ -0,0 +1,10 @@
import { Module } from "@nestjs/common";
import { JwtStrategy } from "./jwt.strategy";
import { PassportModule } from "@nestjs/passport";
@Module({
imports: [PassportModule.register({ defaultStrategy: "jwt" })],
providers: [JwtStrategy],
exports: [PassportModule]
})
export class AuthenticationModule {}

View file

@ -0,0 +1,30 @@
import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { passportJwtSecret } from "jwks-rsa";
import { ExtractJwt, Strategy } from "passport-jwt";
import { ConfigService } from "@nestjs/config";
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private readonly config: ConfigService) {
super({
secretOrKeyProvider: passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `${config.get<string>(
"JWT_AUTH0_DOMAIN"
)}.well-known/jwks.json`
}),
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
audience: config.get<string>("JWT_AUTH0_AUDIENCE"),
issuer: config.get<string>("JWT_AUTH0_DOMAIN"),
algorithms: ["RS256"]
});
}
validate(payload: any) {
return payload;
}
}

View file

@ -0,0 +1,3 @@
export enum ConnectionType {
SPOTIFY = "spotify"
}

View file

@ -0,0 +1,14 @@
import { Entity, Column, PrimaryGeneratedColumn } from "typeorm";
import { ConnectionType } from "./connection-type.enum";
@Entity()
export class Connection {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
userID: string;
@Column()
type: ConnectionType;
}

View file

@ -0,0 +1,18 @@
import { Test, TestingModule } from "@nestjs/testing";
import { ConnectionsController } from "./connections.controller";
describe("Connections Controller", () => {
let controller: ConnectionsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [ConnectionsController]
}).compile();
controller = module.get<ConnectionsController>(ConnectionsController);
});
it("should be defined", () => {
expect(controller).toBeDefined();
});
});

View file

@ -0,0 +1,4 @@
import { Controller } from "@nestjs/common";
@Controller("connections")
export class ConnectionsController {}

View file

@ -0,0 +1,12 @@
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { ConnectionsController } from "./connections.controller";
import { ConnectionsRepository } from "./connections.repository";
import { ConnectionsService } from "./connections.service";
@Module({
imports: [TypeOrmModule.forFeature([ConnectionsRepository])],
controllers: [ConnectionsController],
providers: [ConnectionsService]
})
export class ConnectionsModule {}

View file

@ -0,0 +1,5 @@
import { EntityRepository, Repository } from "typeorm";
import { Connection } from "./connection.entity";
@EntityRepository(Connection)
export class ConnectionsRepository extends Repository<Connection> {}

View file

@ -0,0 +1,18 @@
import { Test, TestingModule } from "@nestjs/testing";
import { ConnectionsService } from "./connections.service";
describe("ConnectionsService", () => {
let service: ConnectionsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ConnectionsService]
}).compile();
service = module.get<ConnectionsService>(ConnectionsService);
});
it("should be defined", () => {
expect(service).toBeDefined();
});
});

View file

@ -0,0 +1,7 @@
import { Injectable } from "@nestjs/common";
import { ConnectionsRepository } from "./connections.repository";
@Injectable()
export class ConnectionsService {
constructor(private readonly connectionRepository: ConnectionsRepository) {}
}

View file

@ -0,0 +1,25 @@
import { ConfigModule, ConfigService } from "@nestjs/config";
import { TypeOrmModule } from "@nestjs/typeorm";
import { join } from "path";
// tslint:disable-next-line variable-name
export const DatabaseModule = TypeOrmModule.forRootAsync({
useFactory: (config: ConfigService) => ({
type: "postgres",
// Connection details
host: config.get<string>("DB_HOST"),
username: config.get<string>("DB_USERNAME"),
password: config.get<string>("DB_PASSWORD"),
database: config.get<string>("DB_DATABASE"),
// Entities
entities: [join(__dirname, "..", "**/*.entity.{ts,js}")],
// Migrations
migrationsRun: true,
migrations: [join(__dirname, "migrations", "*.{ts,js}")],
synchronize: false
}),
inject: [ConfigService]
});

8
src/main.ts Normal file
View file

@ -0,0 +1,8 @@
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();