Skip to content

Commit

Permalink
[Auth] Setup Done.
Browse files Browse the repository at this point in the history
[Blogs] Setup Done.
  • Loading branch information
lovishGIT committed Nov 18, 2024
0 parents commit 5cf4e4d
Show file tree
Hide file tree
Showing 15 changed files with 473 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.vscode

node_modules
package-lock.json
src/config/serviceAccount.json
src/config/firebaseConfig.json

.env
82 changes: 82 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Blog App

## Description
The Blog App is a web application that allows users to create, edit, and delete blog posts. Users can also view posts created by others and leave comments.

## Features
- User authentication and authorization
- Create, edit, and delete blog posts
- View all blog posts
- Comment on blog posts
- Responsive design

## Technologies Used
- Frontend: HTML, CSS, JavaScript, React
- Backend: Node.js, Express
- Database: MongoDB
- Authentication: JWT

## Installation
1. Clone the repository:
```bash
git clone https://github.com/yourusername/blog-app.git
```
2. Navigate to the project directory:
```bash
cd blog-app
```
3. Install dependencies:
```bash
npm install
```
4. Set up environment variables:
- Create a `.env` file in the root directory
- Add the following variables:
```
PORT=5000
JWT_SECRET=your_jwt_secret
```
5. Set up firebase:
- Create a new project on Firebase
- Add a web app to the project
- Copy the Firebase configuration object
- Create a `firebase.js` file in the `src` directory
- Add the following code to the src/config/firebaseConfig.json file:
```javascript
{
"apiKey": 'your_api_key',
"authDomain": 'your_auth_domain',
"projectId": 'your_project_id',
"storageBucket": 'your_storage_bucket',
"messagingSenderId": 'your_messaging_sender_id',
"appId": 'your_app_id'
};
```
- Add the following Code to src/config/serviceAccount.json file:
```javascript
{
"type": "service_account",
"project_id": "your_project_id",
"private_key_id": "your_private_key_id",
"private_key": "your_private_key",
"client_email": "your_client_email",
"client_id": "your_client_id",
"auth_uri": "your_auth_uri",
"token_uri": "your_token_uri",
"auth_provider_x509_cert_url": "your_auth_provider_x509_cert_url",
"client_x509_cert_url": "your_client_x509_cert_url"
}
```

## Usage
1. Start the development server:
```bash
npm start
```
2. Open your Postman and hit `http://localhost:5000`

## Contributing
Contributions are welcome! Please fork the repository and create a pull request.

## License
This project is licensed under the MIT License.
25 changes: 25 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import express from 'express';
import authRoutes from './src/routes/auth.routes.js';
import blogRoutes from './src/routes/blog.routes.js';

const app = express();

// app.use(cors({
// origin: 'http://localhost:5173',
// credentials: true,
// }));

app.use(express.json());
app.use(express.urlencoded({ extended: true }));


app.get('/', (req, res) => {
return res.json({
status: 'success',
message: 'Welcome to the Blog API!',
});
});
app.use('/api/auth', authRoutes);
app.use('/api/blogs', blogRoutes);

export default app;
26 changes: 26 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "blog-app",
"version": "1.0.0",
"description": "",
"main": "server.js",
"type": "module",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.1",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.21.1",
"firebase": "^11.0.2",
"firebase-admin": "^13.0.0"
},
"devDependencies": {
"nodemon": "^3.1.7"
}
}
9 changes: 9 additions & 0 deletions server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import "dotenv/config";
import app from "./app.js";
import "./src/config/firebase.js";

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
24 changes: 24 additions & 0 deletions src/config/firebase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Import necessary packages
import admin from 'firebase-admin';
import { initializeApp } from 'firebase/app';
import { getAuth as getClientAuth } from 'firebase/auth';

// Import config files
import firebaseConfig from './firebaseConfig.json' assert { type: 'json' }; // Firebase config for the client-side
import serviceAccount from './serviceAccount.json' assert { type: 'json' }; // Service account for the Admin SDK

// Initialize Firebase Client SDK (for frontend or client-side interaction)
const app = initializeApp(firebaseConfig); // Using firebaseConfig for client-side initialization
const clientAuth = getClientAuth(app); // Firebase Client Auth

// Initialize Firebase Admin SDK (for backend interaction)
admin.initializeApp({
credential: admin.credential.cert(serviceAccount), // Using serviceAccount for admin-side authentication
databaseURL: 'https://your-project-id.firebaseio.com', // Your Firebase Database URL
});

// Firestore and Auth from Admin SDK
export const db = admin.firestore(); // Admin SDK Firestore
export const adminAuth = admin.auth(); // Admin SDK Authentication

export { clientAuth }; // Exporting clientAuth separately for use on the client-side
13 changes: 13 additions & 0 deletions src/config/firebase.rules.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /blogs/{blogId} {
allow read: if true; // Allow read for all
allow write: if request.auth != null; // Allow write if user is authenticated
}
match /users/{userId} {
allow read: if resource.id == request.auth.uid; // Allow users to read their own data
allow write: if resource.id == request.auth.uid; // Allow users to write their own data
}
}
}
90 changes: 90 additions & 0 deletions src/controllers/auth.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { log } from 'console';
import {
getAuth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
} from 'firebase/auth';
import { db, clientAuth } from '../config/firebase.js'; // Using the Firebase Client Auth

import admin from 'firebase-admin'; // Admin SDK to manage users in Firestore


export const signup = async (req, res) => {
const { email, password, name } = req.body;

try {
log('signup');
// Use the clientAuth (Firebase Auth SDK) to create user
const userCredential = await createUserWithEmailAndPassword(
clientAuth, // client-side Firebase auth
email,
password
);
const user = userCredential.user;

// Storing additional user data in Firestore (using Admin SDK)
await db.collection('users').doc(user.uid).set({
email,
name,
});

// Get Firebase ID token for session management
const idToken = await user.getIdToken();

// Set cookie for authentication
res.cookie('authToken', idToken, {
httpOnly: true, // Ensure the cookie cannot be accessed by JavaScript
secure: process.env.NODE_ENV === 'production', // Set secure cookie in production
maxAge: 24 * 60 * 60 * 1000, // Expire after 1 day
sameSite: 'strict', // Prevent cross-site request forgery
});

return res.status(201).json({
message: 'User registered successfully',
idToken,
});
} catch (error) {
return res.status(400).json({ error: error.message });
}
};

export const login = async (req, res) => {
const { email, password } = req.body;

try {
// Use the clientAuth (Firebase Auth SDK) to sign in the user
const userCredential = await signInWithEmailAndPassword(
clientAuth, // client-side Firebase auth
email,
password
);
const user = userCredential.user;

// Get Firebase ID token for session management
const idToken = await user.getIdToken();

// Set cookie for authentication
res.cookie('authToken', idToken, {
httpOnly: true, // Ensure the cookie cannot be accessed by JavaScript
secure: process.env.NODE_ENV === 'production', // Set secure cookie in production
maxAge: 24 * 60 * 60 * 1000, // Expire after 1 day
sameSite: 'strict', // Prevent cross-site request forgery
});

return res.status(200).json({
message: 'Login successful',
});
} catch (error) {
return res.status(400).json({ error: error.message });
}
};

export const logout = (req, res) => {
res.clearCookie('authToken', {
httpOnly: true,
sameSite: 'strict',
});
return res
.status(200)
.json({ message: 'Logged out successfully' });
};
Loading

0 comments on commit 5cf4e4d

Please sign in to comment.