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

[Fixed] CORS error and refactor server configuration #45

Merged
merged 27 commits into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
89ca5b0
Add start.sh to .gitignore
ballyalley-o Mar 24, 2024
0c282e9
Update good-logs package version to 1.2.3
ballyalley-o Mar 24, 2024
c4f3a62
cors origins added, styles added API and file upload configuration,
ballyalley-o Mar 24, 2024
1218bed
Add sample.env file with fake environment variables
ballyalley-o Mar 24, 2024
32d4144
Move header to middleware #43: moved header to middleware to use new…
ballyalley-o Mar 24, 2024
2bf6e5d
Remove unused import in config/index.ts
ballyalley-o Mar 24, 2024
a89ffa4
Move header to middleware #43: Refactor server configuration and midd…
ballyalley-o Mar 24, 2024
86119bc
[BUG: Server] Cors error #40: 🌈 style(Refactor code and fix formattin…
ballyalley-o Mar 24, 2024
d36e030
🌈 style(Refactor code and fix formatting issues):
ballyalley-o Mar 24, 2024
8b25a7f
🌈 style(Refactor code and fix formatting issues & removed logging for…
ballyalley-o Mar 24, 2024
72ec8c1
🌈 style(Refactor course controller formatting):
ballyalley-o Mar 24, 2024
8bffe59
🌈 style(Refactor FeedbackController formatting):
ballyalley-o Mar 24, 2024
dc32f2a
Refactor debugger decorator to use good-logs * added styles 🌈
ballyalley-o Mar 24, 2024
0ebcef0
🌈 style(Refactor LogRequest code formatting):
ballyalley-o Mar 24, 2024
d3f947a
🌈 style(Refactor middleware and decorator code formatting):
ballyalley-o Mar 24, 2024
c73351b
[BUG FIX: Server] Cors error #40 Add CORS configuration middleware
ballyalley-o Mar 24, 2024
6cbc460
🌈 style(Refactor error-handler middleware code formatting):
ballyalley-o Mar 24, 2024
1245900
Remove logger middleware, replaced by good-logs
ballyalley-o Mar 24, 2024
6c6c317
🌈 style(Refactor BootcampSchema pre-remove hook code styling):
ballyalley-o Mar 24, 2024
5ee0e05
🌈 style(Refactor CourseSchema code styling):
ballyalley-o Mar 24, 2024
8119a50
🌈 style(Refactor bootcamp routes code styling):
ballyalley-o Mar 24, 2024
6ed05d6
🌈 style(Refactor sendEmail function code styling):
ballyalley-o Mar 24, 2024
544fb14
init .prettierrc configuration file
ballyalley-o Mar 24, 2024
7e0c40f
[ Fix ] upload photo field for bootcamp #41: Update photo path in Boo…
ballyalley-o Mar 24, 2024
a844bc7
Limit the description #42: Update MAX_LENGTH_DESCRIPTION in SCHEMA enum
ballyalley-o Mar 24, 2024
a3156f6
Limit the description #42: Fix code formatting and syntax issues in B…
ballyalley-o Mar 24, 2024
1f7ba5d
Merge pull request #44 from ballyalley-o/TCCPISSUE40-cors-error
ballyalley-o Mar 24, 2024
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ dist
tsconfig.tsbuildinfo

updtlog.sh
start.sh

public/upload/tccp-*.*
public/avatar/tccp-*.*
20 changes: 20 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"printWidth": 150,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"trailingComma": "none",
"bracketSpacing": true,
"jsxBracketSameLine": true,
"arrowParens": "always",
"requirePragma": false,
"insertPragma": false,
"proseWrap": "preserve",
"htmlWhitespaceSensitivity": "css",
"vueIndentScriptAndStyle": false,
"endOfLine": "auto",
"embeddedLanguageFormatting": "auto"
}
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"express-fileupload": "^1.4.3",
"express-mongo-sanitize": "^2.2.0",
"express-rate-limit": "^7.1.5",
"good-logs": "^1.2.2",
"good-logs": "^1.2.3",
"helmet": "^7.1.0",
"hpp": "^0.2.3",
"jsonwebtoken": "^9.0.2",
Expand All @@ -66,4 +66,4 @@
"tsc-alias": "^1.8.8",
"typedoc": "^0.25.8"
}
}
}
43 changes: 43 additions & 0 deletions sample.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
API_HOST=http://localhost:{PORT}
API_URL=http://localhost:{PORT}/api
CLIENT_URL=https://fakeprojct.com
CORS_ALLOWED_ORIGIN=https://fakeprojct.com,http://localhost:5173,http://localhost:5174
API_VERSION=/v1.0.3
PORT=3003
DEV_CLIENT_PORT=5173
NODE_ENV=production

# Database
# db
DB_URI=mongodb+srv://fakeuser:[email protected]/FakeDB?retryWrites=true&w=majority
DB_NAME=FakeDB
DB_PROTOCOL=mongodb+srv://
DB_HOST=fakecluster.mongodb.net
DB_USER=fakeuser
DB_PW=fakepassword

# jwt
JWT_SECRET=fakeServer
JWT_EXP=30d
JWT_COOKIE_EXPIRE=

# mail - mailtrap
SMTP_HOST=fake.smtp.mailtrap.io
SMTP_PORT=2525
SMTP_EMAIL=fakeemail
SMTP_PASSWORD=fakepassword
FROM_EMAIL=[email protected]
FROM_NAME=FakeName

# rate limit
RATE_LIMIT=100

# neocoder
GEOCODER_PROVIDER=fakeprovider
GEOCODER_API_KEY=fakeapikey

# photo
FILE_UPLOAD_PATH=./public/upload
AVATAR_UPLOAD_PATH=./public/avatar
MAX_FILE_UPLOAD=1000000
MAX_AVATAR_UPLOAD=500000
23 changes: 8 additions & 15 deletions src/config/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@ dotenv.config()
const GLOBAL = {
APP_NAME: 'The CodeCoach Projct',
APP_SERVER_NAME: 'tccp-server',
API_HOST: conNex(
process.env.API_HOST?.replace('{PORT}', process.env.PORT ?? '') || ''
),
API_URL: conNex(
process.env.API_URL?.replace('{PORT}', process.env.PORT ?? '') || '',
process.env.API_VERSION || ''
),
API_HOST: conNex(process.env.API_HOST?.replace('{PORT}', process.env.PORT ?? '') || ''),
API_URL: conNex(process.env.API_URL?.replace('{PORT}', process.env.PORT ?? '') || '', process.env.API_VERSION || ''),
CLIENT_DEV_URL: conNex(process.env.API_HOST?.replace('{PORT}', process.env.DEV_CLIENT_PORT ?? '') || ''),
CORS_ALLOWED_ORIGIN: process.env.CORS_ALLOWED_ORIGIN?.split(',') || [],
API_VERSION: process.env.API_VERSION || '',
PORT: process.env.PORT || 3005,
ENV: process.env.NODE_ENV || '',
Expand All @@ -33,15 +30,11 @@ const GLOBAL = {
MAX_FILE_UPLOAD: process.env.MAX_FILE_UPLOAD || NumKey.ONE_MB,
PHOTO_UPLOAD_PATH: process.env.PHOTO_UPLOAD_PATH,

PHOTO_FILENAME: (bootcampId: ObjectId, name: string) =>
`tccp-${bootcampId}${path.parse(name).ext}`,
AVATAR_FILENAME: (userId: ObjectId, name: string) =>
`tccp-av-${userId}${path.parse(name).ext}`,
PHOTO_FILENAME: (bootcampId: ObjectId, name: string) => `tccp-${bootcampId}${path.parse(name).ext}`,
AVATAR_FILENAME: (userId: ObjectId, name: string) => `tccp-av-${userId}${path.parse(name).ext}`,

PHOTO_UPLOAD_MV: (photo: any, cb: any) =>
photo.mv(`${process.env.FILE_UPLOAD_PATH}/${photo.name}`, cb),
AVATAR_UPLOAD_MV: (photo: any, cb: any) =>
photo.mv(`${process.env.AVATAR_UPLOAD_PATH}/${photo.name}`, cb),
PHOTO_UPLOAD_MV: (photo: any, cb: any) => photo.mv(`${process.env.FILE_UPLOAD_PATH}/${photo.name}`, cb),
AVATAR_UPLOAD_MV: (photo: any, cb: any) => photo.mv(`${process.env.AVATAR_UPLOAD_PATH}/${photo.name}`, cb),

// @mail - nodemailer - mailtrap
MAIL_FROM: `${process.env.FROM_NAME} <${process.env.FROM_EMAIL}>`,
Expand Down
17 changes: 0 additions & 17 deletions src/config/header.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import path from 'path'
export { default as App } from '@config/server'
export { default as setHeader } from '@config/header'
export { default as connectDb } from '@config/db'
export { default as GLOBAL } from '@config/global'

Expand Down
22 changes: 6 additions & 16 deletions src/config/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import mongoSanitize from 'express-mongo-sanitize'
import helmet from 'helmet'
import hpp from 'hpp'
import rateLimit from 'express-rate-limit'
import { setHeader, connectDb } from '@config'
import { connectDb } from '@config'
import { AppRouter } from '@app-router'
import { mainRoute } from '@route'
import { xssHandler, errorHandler, notFound } from '@middleware'
import { xssHandler, errorHandler, notFound, corsConfig } from '@middleware'
import { LogInitRequest, ServerStatus } from '@decorator'
import { Key } from '@constant/enum'
import options from '@util/geocoder'
Expand Down Expand Up @@ -95,15 +95,15 @@ class App {
this._app.use(express.static(Key.Public))
this._app.use(morgan(Key.MorganDev))
this._app.use(cookieParser())
this._app.use(cors())
this._app.use(setHeader)
this._app.use(fileupload())
this._app.use(cors(corsConfig))
this._app.use(mongoSanitize())
this._app.use(helmet())
this._app.use(xssHandler)
this._app.use(rateLimit(GLOBAL.LIMITER))
this._app.use(hpp())
this.registerRoute()

this._app.use(errorHandler)
this._app.use(notFound)
}
Expand Down Expand Up @@ -147,21 +147,11 @@ class App {

try {
this._app.listen(GLOBAL.PORT, () => {
goodlog.server(
GLOBAL.PORT as number,
GLOBAL.API_VERSION,
prod,
this.isConnected
)
goodlog.server(GLOBAL.PORT as number, GLOBAL.API_VERSION, prod, this.isConnected)
})
} catch (error: any) {
process.on(Key.UnhandledRejection, (err) => {
goodlog.server(
GLOBAL.PORT as number,
GLOBAL.API_VERSION,
prod,
this.isConnected
)
goodlog.server(GLOBAL.PORT as number, GLOBAL.API_VERSION, prod, this.isConnected)
goodlog.error(error.message)
this.isConnected = false
})
Expand Down
6 changes: 3 additions & 3 deletions src/constant/enum/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ enum SCHEMA {
NAME = 'Please add a bootcamp name/title',
MAX_LENGTH_NAME = 'Name can not be more than 50 characters',
DESCRIPTION = 'Please add a description',
MAX_LENGTH_DESCRIPTION = 'Description can not be more than 500 characters',
MAX_LENGTH_DESCRIPTION = 'Description can not be more than 250 characters',
URL = 'Please use a valid URL with HTTP or HTTPS',
MAX_LENGTH_PHONE = 'Phone number can not be longer than 20 characters',
EMAIL = 'Please add a valid email',
Expand All @@ -27,7 +27,7 @@ enum SCHEMA {
// @user
FIRST_NAME = 'Please provide your first name',
LAST_NAME = 'Please provide your family/last name',
PASSWORD = 'Please add a password',
PASSWORD = 'Please add a password'
}

export default SCHEMA
export default SCHEMA;
22 changes: 8 additions & 14 deletions src/constant/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ const RESPONSE = {
204: 'NO CONTENT: The server successfully processed the request but there is no content to send in the response.',
PHOTO_UPLOADED: 'OK: Photo Uploaded',
AVATAR_UPLOADED: 'OK: Avatar Uploaded',
COURSES_DELETED: (data: string) =>
`Courses being deleted from bootcamp ID: ${data}. Reload page to see the effect`,
COURSES_DELETED: (data: string) => `Courses being deleted from bootcamp ID: ${data}. Reload page to see the effect`,
COLLECTION_SEED: ' MOCK MIGRATION SUCCESSFUL 🌱 ',
COLLECTION_DESTROYED: ' COLLECTION/s DESTROYED 💥 ',
LOGOUT: `User logged out`,
Expand All @@ -49,28 +48,23 @@ const RESPONSE = {
500: 'INTERNAL SERVER ERROR: Server encountered an Unhandled Exception',
503: 'SERVICE UNAVAILABLE: The server is temporarily unable to handle the Request',
504: 'GATEWAY TIMEOUT: The server acting as a gateway did not receive a timely response from an upstream server',
CORS_NOT_ALLOWED: 'CORS ERROR: Not allowed by Access-Control-Allow-Origin',
ENTITY_EXISTS: 'Entity already exists',
ALREADY_EXISTS: (data: string) => `${data} already exists`,
NOT_FOUND_COURSE: (data: string) => `Course not found with id of ${data}`,
NOT_FOUND_BOOTCAMP: (data: string) =>
`Bootcamp not found with id of ${data}`,
NOT_FOUND_FEEDBACK: (data: string) =>
`No feedback found with the id ${data}`,
NOT_FOUND_BOOTCAMP: (data: string) => `Bootcamp not found with id of ${data}`,
NOT_FOUND_FEEDBACK: (data: string) => `No feedback found with the id ${data}`,
NOT_FOUND: (data: string) => `There is no user with id ${data}`,
BOOTCAMP_ALREADY_PUBLISHED: (data: string) =>
`The user with ID ${data} has already published a bootcamp`,
BOOTCAMP_ALREADY_PUBLISHED: (data: string) => `The user with ID ${data} has already published a bootcamp`,
FAILED_UPLOAD: ' Please upload a file ',
FAILED_UPLOAD_AVATAR: ' Please upload an avatar ',
FAILED_FILESIZE: (fileSize: number) =>
`File size cannot exceed ${fileSize}`,
FAILED_FILESIZE: (fileSize: number) => `File size cannot exceed ${fileSize}`,
FAILED_SEED: ' FAILED TO SEED COLLECTION/s SEED ',
FAILED_DESTROY: ' FAILED TO DESTROY COLLECTION/s ',
INVALID_CREDENTIAL: 'Please provide a valid email and password',
INVALID_TOKEN: 'Invalid token',
NOT_OWNER: (user: string, course: string) =>
`User ${user} is unauthorized to update course ${course}`,
ROLE_NOT_ALLOWED: (data: string) =>
`Current role ${data} is unauthorized to access this route`,
NOT_OWNER: (user: string, course: string) => `User ${user} is unauthorized to update course ${course}`,
ROLE_NOT_ALLOWED: (data: string) => `Current role ${data} is unauthorized to access this route`,
parseErr: (err: any) => `Error parsing JSON: ${err}`,
NotInstance: 'This class cannot be instantiated',
STATIC_CLASS: 'This is a static class',
Expand Down
Loading