Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create an internal lib for configuration #443

Merged
merged 6 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# General
BACKEND_APP_PORT=3000
FRONTEND_APP_PORT=5000
NODE_ENV=development

# RATE LIMIT
RATE_LIMIT_TTL=60
RATE_LIMIT_COUNT=10

# LOGGER
LOGGER_CONSOLE_THRESHOLD=INFO # DEBUG, INFO, WARN, ERROR, FATAL

# FRONTEND
DOMAIN=localhost
CLIENTSIDE_API_DOMAIN=http://localhost:3000 # Use this verible, while making client side API calls
API_DOMAIN=http://localhost:3000 # If you are running with docker compose change this to http://backend:3000

# DATABASE
# If you are running with docker compose change host to postgres
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/reduced_to_db?schema=public"

# REDIS
REDIS_ENABLE=false
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=password
REDIS_TTL=604800000 # 1 week in milliseconds

# AUTH
JWT_ACCESS_SECRET=abc1234
JWT_REFRESH_SECRET=abc1234

# NOVU - You don't need this when running locally (just verify your email from the database)
NOVU_API_KEY=Get it from https://novu.co/

9 changes: 6 additions & 3 deletions apps/backend/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
Dockerfile
.dockerignore
node_modules
dist
npm-debug.log
dist
CONTRIBUTE.MD
README.md
.gitignore
LICENSE
.DS_Store
30 changes: 0 additions & 30 deletions apps/backend/.env.example

This file was deleted.

16 changes: 10 additions & 6 deletions apps/backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
# Dependencies Stage
# --------------------------------------------
FROM node:19.2-alpine3.15 as dependencies

WORKDIR /app
COPY package.json package-lock.json ./

COPY package*.json ./

RUN apk add --update python3 make g++\
&& rm -rf /var/cache/apk/*
Expand All @@ -24,20 +24,24 @@ COPY --from=dependencies /app/node_modules ./node_modules
# Run prisma generate & build the bundle in production mode
RUN npx nx build backend --prod --skip-nx-cache


# --------------------------------------------
# Production Stage
# --------------------------------------------
FROM node:19.2-alpine3.15 as production
WORKDIR /app

COPY --from=build /app/dist/apps/backend ./backend
COPY --from=build /app/dist/libs/prisma ./prisma
COPY --from=build /app/node_modules ./node_modules
COPY ./libs/ ./libs/
COPY ./nx.json ./nx.json
COPY --from=build /app/libs/ ./libs

EXPOSE 3000

# Start the application
CMD sh -c "npx nx migrate-deploy prisma && node backend/main.js"







3 changes: 1 addition & 2 deletions apps/backend/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { APP_GUARD } from '@nestjs/core';
import { ThrottlerModule } from '@nestjs/throttler';
import { AuthModule } from './auth/auth.module';
import { AppCacheModule } from './cache/cache.module';
import { AppConfigModule } from './config/config.module';
import { AppConfigService } from './config/config.service';
import { AppConfigModule, AppConfigService } from '@reduced.to/config';
import { AppLoggerModule } from './logger/logger.module';
import { NovuModule } from './novu/novu.module';
import { PrismaService } from '@reduced.to/prisma';
Expand Down
8 changes: 4 additions & 4 deletions apps/backend/src/auth/auth.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { NovuService } from '../novu/novu.service';
import { PrismaService } from '@reduced.to/prisma';
import { AppConfigService } from '../config/config.service';
import { AppConfigService, Configuration } from '@reduced.to/config';
import { SignupDto } from './dto/signup.dto';
import { UserContext } from './interfaces/user-context';
import { LocalAuthGuard } from './guards/local.guard';
Expand Down Expand Up @@ -36,9 +36,9 @@ describe('AuthController', () => {
};

const MOCK_TOKENS = { accessToken: 'access_token', refreshToken: 'refresh_token' };
const MOCK_CONFIG = {
front: { domain: 'example.com' },
app: { env: 'production' },
const MOCK_CONFIG: Partial<Configuration> = {
front: { domain: 'example.com', apiDomain: 'http://localhost:3000', clientSideApiDomain: 'http://localhost:3000' },
general: { env: 'production', backendPort: 3000, frontendPort: 5000 },
jwt: {
accessSecret: 'secret',
refreshSecret: 'secret',
Expand Down
4 changes: 2 additions & 2 deletions apps/backend/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Body, Controller, Get, Post, Req, Res, UnauthorizedException, UseGuards } from '@nestjs/common';
import { Request, Response } from 'express';
import { AppConfigService } from '../config/config.service';
import { AppConfigService } from '@reduced.to/config';
import { NovuService } from '../novu/novu.service';
import { PrismaService } from '@reduced.to/prisma';
import { AuthService } from './auth.service';
Expand Down Expand Up @@ -44,7 +44,7 @@ export class AuthController {
const user = await this.authService.signup(signupDto);

// Send verification email to user if in production
if (this.appConfigService.getConfig().app.env === 'production') {
if (this.appConfigService.getConfig().general.env === 'production') {
await this.novuService.sendVerificationEmail(user);
}

Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/auth/auth.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { AppConfigService } from '../config/config.service';
import { AppConfigService } from '@reduced.to/config';
import { NovuModule } from '../novu/novu.module';
import { NovuService } from '../novu/novu.service';
import { PrismaModule } from '@reduced.to/prisma';
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/auth/auth.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { JwtService } from '@nestjs/jwt';
import { Test, TestingModule } from '@nestjs/testing';
import { Role, User } from '@reduced.to/prisma';
import * as bcrypt from 'bcryptjs';
import { AppConfigModule } from '../config/config.module';
import { AppConfigModule } from '@reduced.to/config';
import { PrismaService } from '@reduced.to/prisma';
import { AuthService } from './auth.service';

Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { Role } from '@reduced.to/prisma';
import * as bcrypt from 'bcryptjs';
import { AppConfigService } from '../config/config.service';
import { AppConfigService } from '@reduced.to/config';
import { PrismaService } from '@reduced.to/prisma';
import { SignupDto } from './dto/signup.dto';
import { UserContext } from './interfaces/user-context';
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/auth/strategies/jwt-refresh.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Request } from 'express';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { AppConfigService } from '../../config/config.service';
import { AppConfigService } from '@reduced.to/config';
import { AuthService } from '../auth.service';

@Injectable()
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/auth/strategies/jwt.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { AppConfigService } from '../../config/config.service';
import { AppConfigService } from '@reduced.to/config';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/auth/strategies/verify.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { AppConfigService } from '../../config/config.service';
import { AppConfigService } from '@reduced.to/config';

@Injectable()
export class VerifyStrategy extends PassportStrategy(Strategy, 'verify') {
Expand Down
8 changes: 1 addition & 7 deletions apps/backend/src/auth/utils/cookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,7 @@ export const setAuthCookies = (
refreshToken: string;
}
) => {
// get the host from the domain (remove port if present)
// for example: localhost:5155 -> localhost
// for example: reduced.to -> reduced.to
const strippedDomain = rawDomain
.replace(/http(s)?(:)?(\/\/)?|(\/\/)?(www\.)?/g, '') // strip prefix
.replace(/:\d+$/g, ''); // strip port
const domain = process.env.NODE_ENV === 'production' ? `.${strippedDomain}` : strippedDomain;
const domain = process.env.NODE_ENV === 'production' ? `.${rawDomain}` : rawDomain;

res
.cookie(AUTH_COOKIE_NAME, tokens.accessToken, {
Expand Down
3 changes: 1 addition & 2 deletions apps/backend/src/cache/cache.module.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { CacheModule, CacheStore } from '@nestjs/cache-manager';
import { Global, Module } from '@nestjs/common';
import { RedisStore, redisStore } from 'cache-manager-redis-store';
import { AppConfigModule } from '../config/config.module';
import { AppConfigService } from '../config/config.service';
import { AppConfigService, AppConfigModule } from '@reduced.to/config';
import { AppCacheService } from './cache.service';

@Global()
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/logger/logger.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppConfigModule } from '../config/config.module';
import { AppConfigModule } from '@reduced.to/config';
import { AppLoggerSerivce } from './logger.service';

describe('LoggerService', () => {
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/logger/logger.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable, LoggerService, LogLevel } from '@nestjs/common';
import { ConsoleTransport, Logger } from '@origranot/ts-logger';
import { AppConfigService } from '../config/config.service';
import { AppConfigService } from '@reduced.to/config';

@Injectable()
export class AppLoggerSerivce implements LoggerService {
Expand Down
4 changes: 2 additions & 2 deletions apps/backend/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { NestExpressApplication } from '@nestjs/platform-express';
import { useContainer } from 'class-validator';
import cookieParser from 'cookie-parser';
import { AppModule } from './app.module';
import { AppConfigService } from './config/config.service';
import { AppConfigService } from '@reduced.to/config';

async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
Expand All @@ -22,7 +22,7 @@ async function bootstrap() {
// Enable DI in class-validator
useContainer(app.select(AppModule), { fallbackOnErrors: true });

const port = app.get(AppConfigService).getConfig().app.port;
const port = app.get(AppConfigService).getConfig().general.backendPort;

await app.listen(port);
}
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/novu/novu.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { AppConfigService } from '../config/config.service';
import { AppConfigService } from '@reduced.to/config';
import { Novu } from '@novu/node';

export const NOVU_INJECTION_TOKEN = 'NOVU';
Expand Down
12 changes: 10 additions & 2 deletions apps/backend/src/novu/novu.service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import { Inject, Injectable } from '@nestjs/common';
import { Novu } from '@novu/node';
import { UserContext } from '../auth/interfaces/user-context';
import { AppConfigService } from '../config/config.service';
import { AppConfigService } from '@reduced.to/config';
import { NOVU_INJECTION_TOKEN } from './novu.module';
import { Configuration } from '@reduced.to/config';

@Injectable()
export class NovuService {
constructor(@Inject(NOVU_INJECTION_TOKEN) private readonly novu: Novu, private readonly appConfigService: AppConfigService) {}
private config: Configuration;
constructor(@Inject(NOVU_INJECTION_TOKEN) private readonly novu: Novu, private readonly appConfigService: AppConfigService) {
this.config = this.appConfigService.getConfig();
}

async sendVerificationEmail(user: UserContext) {
const domain =
process.env.NODE_ENV === 'production'
? `https://${this.config.front.domain}`
: `http://${this.config.front.domain}:${this.config.general.frontendPort}`;
const verificationUrl = `${this.appConfigService.getConfig().front.domain}/register/verify/${user.verificationToken}`;

await this.novu.trigger('new-user', {
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/shortener/shortener.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AppConfigModule } from '../config/config.module';
import { AppConfigModule } from '@reduced.to/config';
import { AppCacheModule } from '../cache/cache.module';
import { ShortenerService } from './shortener.service';
import { ShortenerController } from './shortener.controller';
Expand Down
4 changes: 2 additions & 2 deletions apps/backend/src/shortener/shortener.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { AppConfigService } from '../config/config.service';
import { AppConfigService } from '@reduced.to/config';
import { ShortenerService } from './shortener.service';
import { Test, TestingModule } from '@nestjs/testing';
import { AppCacheModule } from '../cache/cache.module';
import { AppCacheService } from '../cache/cache.service';
import { AppConfigModule } from '../config/config.module';
import { AppConfigModule } from '@reduced.to/config';
import { PrismaService } from '@reduced.to/prisma';
import { ShortenerDto } from './dto';
import { BadRequestException } from '@nestjs/common';
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/shortener/shortener.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AppCacheService } from '../cache/cache.service';
import { BadRequestException, Injectable } from '@nestjs/common';
import { AppConfigService } from '../config/config.service';
import { AppConfigService } from '@reduced.to/config';
import { PrismaService } from '@reduced.to/prisma';
import { ShortenerDto } from './dto';
import { UserContext } from '../auth/interfaces/user-context';
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/users/users.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { UsersController } from './users.controller';
import { IFindAllOptions, UsersService } from './users.service';
import { User } from '@reduced.to/prisma';
import { JwtAuthGuard } from '../auth/guards/jwt.guard';
import { AppConfigModule } from '../config/config.module';
import { AppConfigModule } from '@reduced.to/config';
import { RolesGuard } from '../auth/guards/roles.guard';
import { IPaginationResult } from '../shared/utils';
import { SortOrder } from '../shared/enums/sort-order.enum';
Expand Down
2 changes: 0 additions & 2 deletions apps/frontend/.example.env

This file was deleted.

6 changes: 2 additions & 4 deletions apps/frontend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@
# Dependencies Stage
# --------------------------------------------
FROM node:19.2-alpine3.15 as dependencies

WORKDIR /app
COPY package.json package-lock.json ./

COPY package*.json ./

RUN apk add --update python3 make g++\
&& rm -rf /var/cache/apk/*

RUN npm ci


# --------------------------------------------
# Build Stage
# --------------------------------------------
Expand All @@ -31,7 +30,6 @@ COPY --from=dependencies /app/node_modules ./node_modules
# Run prisma generate & build the bundle in production mode
RUN npx nx build frontend --prod --skip-nx-cache


# --------------------------------------------
# Production Stage
# --------------------------------------------
Expand Down
Loading