Skip to content

Commit

Permalink
Added Source Code
Browse files Browse the repository at this point in the history
  • Loading branch information
ADITYA 123 committed Apr 17, 2024
0 parents commit 72baf74
Show file tree
Hide file tree
Showing 48 changed files with 18,207 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .env
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
20 changes: 20 additions & 0 deletions Dockerfile
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
89 changes: 89 additions & 0 deletions Manifests/dss.yml
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
35 changes: 35 additions & 0 deletions README.md
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
![](./images/home.jpg)
![](./images/campgrounds.jpg)
![](./images/register.jpg)
169 changes: 169 additions & 0 deletions app.js
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}`)
})


21 changes: 21 additions & 0 deletions cloudinary/index.js
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
}
Loading

0 comments on commit 72baf74

Please sign in to comment.