-
Notifications
You must be signed in to change notification settings - Fork 393
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
ADITYA 123
committed
Apr 17, 2024
0 parents
commit 72baf74
Showing
48 changed files
with
18,207 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
CLOUDINARY_CLOUD_NAME= | ||
CLOUDINARY_KEY= | ||
CLOUDINARY_SECRET= | ||
MAPBOX_TOKEN= | ||
DB_URL=" " | ||
SECRET=devopsshack |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Use Node 18 as parent image | ||
FROM node:18 | ||
|
||
# Change the working directory on the Docker image to /app | ||
WORKDIR /app | ||
|
||
# Copy package.json and package-lock.json to the /app directory | ||
COPY package.json package-lock.json ./ | ||
|
||
# Install dependencies | ||
RUN npm install | ||
|
||
# Copy the rest of project files into this image | ||
COPY . . | ||
|
||
# Expose application port | ||
EXPOSE 3000 | ||
|
||
# Start the application | ||
CMD npm start |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
--- | ||
apiVersion: v1 | ||
kind: Secret | ||
metadata: | ||
name: yelp-camp-secrets | ||
type: Opaque | ||
data: | ||
CLOUDINARY_CLOUD_NAME: ZGlpMnJvenRw | ||
CLOUDINARY_KEY: NzU3NjQzMjU3ODkxMzY0 | ||
CLOUDINARY_SECRET: SHpBeTdPU3VCZjJhSUFSUm5Fd0tIcEVtc01N | ||
MAPBOX_TOKEN: cGsuZXlKMUlqb2lZV1JwYW1GcGMzZGhiQ0lzSW1FaU9pSmpiSFl3TnpKemVHNHhaRzR5TW1wd1ltWm1OSFZ3YlhObUluMC5SVlFZc3UwUnZKZ0NGNTRrMjJkWDBB | ||
DB_URL: bW9uZ29kYitzcnY6Ly9qYWlzd2FsYWRpMjQ2OnNjN1ZHU3lkN2RRQ2NMeTFAY2x1c3RlcjAuaXE2bXV0aC5tb25nb2RiLm5ldC8/cmV0cnlXcml0ZXM9dHJ1ZSZ3PW1ham9yaXR5JmFwcE5hbWU9Q2x1c3RlcjA= | ||
SECRET: ZGV2b3Bzc2hhY2s= | ||
|
||
--- | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: yelp-camp-deployment | ||
spec: | ||
replicas: 1 | ||
selector: | ||
matchLabels: | ||
app: yelp-camp | ||
template: | ||
metadata: | ||
labels: | ||
app: yelp-camp | ||
spec: | ||
containers: | ||
- name: yelp-camp-container | ||
image: adijaiswal/campa:latest | ||
ports: | ||
- containerPort: 3000 | ||
env: | ||
- name: CLOUDINARY_CLOUD_NAME | ||
valueFrom: | ||
secretKeyRef: | ||
name: yelp-camp-secrets | ||
key: CLOUDINARY_CLOUD_NAME | ||
- name: CLOUDINARY_KEY | ||
valueFrom: | ||
secretKeyRef: | ||
name: yelp-camp-secrets | ||
key: CLOUDINARY_KEY | ||
- name: CLOUDINARY_SECRET | ||
valueFrom: | ||
secretKeyRef: | ||
name: yelp-camp-secrets | ||
key: CLOUDINARY_SECRET | ||
- name: MAPBOX_TOKEN | ||
valueFrom: | ||
secretKeyRef: | ||
name: yelp-camp-secrets | ||
key: MAPBOX_TOKEN | ||
- name: DB_URL | ||
valueFrom: | ||
secretKeyRef: | ||
name: yelp-camp-secrets | ||
key: DB_URL | ||
- name: SECRET | ||
valueFrom: | ||
secretKeyRef: | ||
name: yelp-camp-secrets | ||
key: SECRET | ||
livenessProbe: | ||
httpGet: | ||
path: / | ||
port: 3000 | ||
initialDelaySeconds: 30 # Adjust the initial delay here | ||
readinessProbe: | ||
httpGet: | ||
path: / | ||
port: 3000 | ||
initialDelaySeconds: 30 # Adjust the initial delay here | ||
|
||
--- | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
name: yelp-camp-service | ||
spec: | ||
selector: | ||
app: yelp-camp | ||
ports: | ||
- protocol: TCP | ||
port: 3000 | ||
targetPort: 3000 | ||
type: LoadBalancer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Yelp Camp Web Application | ||
|
||
This web application allows users to add, view, access, and rate campgrounds by location. It is based on "The Web Developer Bootcamp" by Colt Steele, but includes several modifications and bug fixes. The application leverages a variety of technologies and packages, such as: | ||
|
||
- **Node.js with Express**: Used for the web server. | ||
- **Bootstrap**: For front-end design. | ||
- **Mapbox**: Provides a fancy cluster map. | ||
- **MongoDB Atlas**: Serves as the database. | ||
- **Passport package with local strategy**: For authentication and authorization. | ||
- **Cloudinary**: Used for cloud-based image storage. | ||
- **Helmet**: Enhances application security. | ||
- ... | ||
|
||
## Setup Instructions | ||
|
||
To get this application up and running, you'll need to set up accounts with Cloudinary, Mapbox, and MongoDB Atlas. Once these are set up, create a `.env` file in the same folder as `app.js`. This file should contain the following configurations: | ||
|
||
```sh | ||
CLOUDINARY_CLOUD_NAME=[Your Cloudinary Cloud Name] | ||
CLOUDINARY_KEY=[Your Cloudinary Key] | ||
CLOUDINARY_SECRET=[Your Cloudinary Secret] | ||
MAPBOX_TOKEN=[Your Mapbox Token] | ||
DB_URL=[Your MongoDB Atlas Connection URL] | ||
SECRET=[Your Chosen Secret Key] # This can be any value you prefer | ||
``` | ||
|
||
After configuring the .env file, you can start the project by running: | ||
```sh | ||
docker compose up | ||
``` | ||
|
||
## Application Screenshots | ||
 | ||
 | ||
 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
if (process.env.NODE_ENV !== "production") { | ||
require('dotenv').config(); | ||
} | ||
|
||
const express = require('express'); | ||
const path = require('path'); | ||
const helmet = require('helmet'); | ||
const passport = require('passport'); | ||
const mongoose = require('mongoose'); | ||
const ejsMate = require('ejs-mate'); | ||
const session = require('express-session'); | ||
const flash = require('connect-flash'); | ||
const methodOverride = require('method-override'); | ||
const LocalStrategy = require('passport-local'); | ||
const mongoSanitize = require('express-mongo-sanitize'); | ||
const ExpressError = require('./utils/ExpressError'); | ||
const User = require('./models/user'); | ||
const userRoutes = require('./routes/users'); | ||
const campgroundRoutes = require('./routes/campgrounds'); | ||
const reviewRoutes = require('./routes/reviews'); | ||
|
||
const MongoDBStore = require("connect-mongo")(session); | ||
|
||
const dbUrl = process.env.DB_URL || 'mongodb://127.0.0.1:27017/yelp-camp'; | ||
|
||
mongoose.connect(dbUrl, { | ||
useNewUrlParser: true, | ||
useCreateIndex: true, | ||
useUnifiedTopology: true, | ||
useFindAndModify: false | ||
}); | ||
|
||
const db = mongoose.connection; | ||
db.on("error", console.error.bind(console, "connection error:")); | ||
db.once("open", () => { | ||
console.log("Database connected"); | ||
}); | ||
|
||
const app = express(); | ||
|
||
app.engine('ejs', ejsMate) | ||
app.set('view engine', 'ejs'); | ||
app.set('views', path.join(__dirname, 'views')) | ||
|
||
app.use(express.urlencoded({ extended: true })); | ||
app.use(methodOverride('_method')); | ||
app.use(express.static(path.join(__dirname, 'public'))) | ||
app.use(mongoSanitize({ | ||
replaceWith: '_' | ||
})) | ||
|
||
const secret = process.env.SECRET || 'thisshouldbeabettersecret!'; | ||
|
||
const store = new MongoDBStore({ | ||
url: dbUrl, | ||
secret, | ||
touchAfter: 24 * 60 * 60 // after 1 day, update the session, else, only update session when something change | ||
}); | ||
|
||
store.on("error", function (e) { | ||
console.log("SESSION STORE ERROR", e) | ||
}) | ||
|
||
const sessionConfig = { | ||
store, | ||
name: 'session', | ||
secret, | ||
resave: false, | ||
saveUninitialized: true, | ||
cookie: { | ||
httpOnly: true, | ||
// secure: true, | ||
expires: Date.now() + 1000 * 60 * 60 * 24 * 7, | ||
maxAge: 1000 * 60 * 60 * 24 * 7 | ||
} | ||
} | ||
|
||
app.use(session(sessionConfig)); | ||
app.use(flash()); | ||
app.use(helmet({ contentSecurityPolicy: false })); | ||
|
||
|
||
const scriptSrcUrls = [ | ||
"https://stackpath.bootstrapcdn.com/", | ||
"https://api.tiles.mapbox.com/", | ||
"https://api.mapbox.com/", | ||
"https://kit.fontawesome.com/", | ||
"https://cdnjs.cloudflare.com/", | ||
"https://cdn.jsdelivr.net", | ||
]; | ||
const styleSrcUrls = [ | ||
"https://kit-free.fontawesome.com/", | ||
"https://stackpath.bootstrapcdn.com/", | ||
"https://api.mapbox.com/", | ||
"https://api.tiles.mapbox.com/", | ||
"https://fonts.googleapis.com/", | ||
"https://use.fontawesome.com/", | ||
]; | ||
const connectSrcUrls = [ | ||
"https://api.mapbox.com/", | ||
"https://a.tiles.mapbox.com/", | ||
"https://b.tiles.mapbox.com/", | ||
"https://events.mapbox.com/", | ||
]; | ||
const fontSrcUrls = []; | ||
|
||
app.use( | ||
helmet.contentSecurityPolicy({ | ||
directives: { | ||
defaultSrc: [], | ||
connectSrc: ["'self'", ...connectSrcUrls], | ||
scriptSrc: ["'unsafe-inline'", "'self'", ...scriptSrcUrls], | ||
styleSrc: ["'self'", "'unsafe-inline'", ...styleSrcUrls], | ||
workerSrc: ["'self'", "blob:"], | ||
objectSrc: [], | ||
imgSrc: [ | ||
"'self'", | ||
"blob:", | ||
"data:", | ||
`https://res.cloudinary.com/${process.env.CLOUDINARY_CLOUD_NAME}/`, | ||
"https://images.unsplash.com/", | ||
], | ||
fontSrc: ["'self'", ...fontSrcUrls], | ||
}, | ||
}) | ||
); | ||
|
||
|
||
app.use(passport.initialize()); | ||
app.use(passport.session()); | ||
passport.use(new LocalStrategy(User.authenticate())); | ||
|
||
passport.serializeUser(User.serializeUser()); | ||
passport.deserializeUser(User.deserializeUser()); | ||
|
||
app.use((req, res, next) => { | ||
res.locals.currentUser = req.user; // req.user is user infomation in session that passport define for us | ||
res.locals.success = req.flash('success'); // message when success is invoked in route handler | ||
res.locals.error = req.flash('error'); | ||
next(); | ||
}) | ||
|
||
|
||
app.use('/', userRoutes); | ||
app.use('/campgrounds', campgroundRoutes) | ||
app.use('/campgrounds/:id/reviews', reviewRoutes) | ||
|
||
|
||
app.get('/', (req, res) => { | ||
res.render('home') | ||
}); | ||
|
||
|
||
app.all('*', (req, res, next) => { | ||
next(new ExpressError('Page Not Found', 404)) | ||
}) | ||
|
||
app.use((err, req, res, next) => { | ||
const { statusCode = 500 } = err; | ||
if (!err.message) err.message = 'Oh No, Something Went Wrong!' | ||
res.status(statusCode).render('error', { err }) | ||
}) | ||
|
||
const port = process.env.PORT || 3000; | ||
app.listen(port, () => { | ||
console.log(`Serving on port ${port}`) | ||
}) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
const cloudinary = require('cloudinary').v2; | ||
const { CloudinaryStorage } = require('multer-storage-cloudinary'); | ||
|
||
cloudinary.config({ | ||
cloud_name: process.env.CLOUDINARY_CLOUD_NAME, | ||
api_key: process.env.CLOUDINARY_KEY, | ||
api_secret: process.env.CLOUDINARY_SECRET | ||
}); | ||
|
||
const storage = new CloudinaryStorage({ | ||
cloudinary, | ||
params: { | ||
folder: 'YelpCamp', | ||
allowedFormats: ['jpeg', 'png', 'jpg'] | ||
} | ||
}); | ||
|
||
module.exports = { | ||
cloudinary, | ||
storage | ||
} |
Oops, something went wrong.