Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
F-777 authored Jan 25, 2025
1 parent f7272ed commit 045fd03
Show file tree
Hide file tree
Showing 41 changed files with 5,269 additions and 1 deletion.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
# e-buddy
# React + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9 changes: 9 additions & 0 deletions Real-Time Massage/real-time.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const io = require("socket.io")(server);

io.on("connection", (socket) => {
console.log("User connected: " + socket.id);

socket.on("send_message", (data) => {
io.to(data.receiverId).emit("receive_message", data);
});
});
8 changes: 8 additions & 0 deletions database/colection/massage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"_id": "64b9c27f4e",
"senderId": "123",
"receiverId": "456",
"content": "Hello, how are you?",
"timestamp": "2025-01-21T14:30:00Z"
}

6 changes: 6 additions & 0 deletions database/colection/user.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"_id": "64b9c25d2f",
"username": "john_doe",
"email": "[email protected]",
"password": "$2b$10$hashedPassword"
}
1 change: 1 addition & 0 deletions database/group_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
id | group_name | member_id | created_at
1 change: 1 addition & 0 deletions database/massage_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
id | sender_id | receiver_id | content | timestamp
1 change: 1 addition & 0 deletions database/user_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
id | username | email password_hash | status
1 change: 1 addition & 0 deletions deploy/conecting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mongoose.connect("mongodb+srv://<username>:<password>@cluster0.mongodb.net/ebuddy");
48 changes: 48 additions & 0 deletions ebuddy/Express.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const express = require("express");
const bodyParser = require("body-parser");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcrypt");
const mongoose = require("mongoose");

const app = express();
const PORT = 3000;

// Middleware
app.use(bodyParser.json());

// MongoDB Connection
mongoose.connect("mongodb://localhost:27017/ebuddy", { useNewUrlParser: true, useUnifiedTopology: true });

// User Schema
const UserSchema = new mongoose.Schema({
username: String,
email: String,
password: String,
});
const User = mongoose.model("User", UserSchema);

// Routes
// Register User
app.post("/api/register", async (req, res) => {
const { username, email, password } = req.body;
const hashedPassword = await bcrypt.hash(password, 10);
const user = new User({ username, email, password: hashedPassword });
await user.save();
res.status(201).json({ message: "User registered successfully" });
});

// Login User
app.post("/api/login", async (req, res) => {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (user && (await bcrypt.compare(password, user.password))) {
const token = jwt.sign({ id: user._id, email: user.email }, "SECRET_KEY", { expiresIn: "1h" });
res.json({ message: "Login successful", token });
} else {
res.status(401).json({ message: "Invalid email or password" });
}
});

app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
16 changes: 16 additions & 0 deletions ebuddy/Socket.io.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
io.on("connection", (socket) => {
console.log("User connected: " + socket.id);

// Bergabung ke grup
socket.on("join_group", (groupId) => {
socket.join(groupId);
console.log(`User ${socket.id} joined group: ${groupId}`);
});

// Kirim pesan ke grup
socket.on("send_group_message", (data) => {
const { groupId, senderId, content } = data;
io.to(groupId).emit("receive_group_message", { senderId, content });
});
});

31 changes: 31 additions & 0 deletions ebuddy/WebSocket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const http = require("http");
const socketIo = require("socket.io");

// Create HTTP server
const server = http.createServer(app);

// Setup Socket.IO
const io = socketIo(server);

io.on("connection", (socket) => {
console.log("User connected: " + socket.id);

// Event: Send message
socket.on("send_message", (data) => {
console.log("Message received:", data);
// Emit message to specific user
io.to(data.receiverId).emit("receive_message", {
senderId: data.senderId,
content: data.content,
});
});

socket.on("disconnect", () => {
console.log("User disconnected: " + socket.id);
});
});

// Start Server
server.listen(3001, () => {
console.log("Real-time server running on http://localhost:3001");
});
10 changes: 10 additions & 0 deletions ebuddy/backend/crypto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const CryptoJS = require("crypto-js");

const encryptMessage = (message, key) => {
return CryptoJS.AES.encrypt(message, key).toString();
};

const decryptMessage = (encryptedMessage, key) => {
const bytes = CryptoJS.AES.decrypt(encryptedMessage, key);
return bytes.toString(CryptoJS.enc.Utf8);
};
43 changes: 43 additions & 0 deletions ebuddy/backend/endpoint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const express = require("express");
const router = express.Router();
const Group = require("./models/Group"); // Model Grup
const User = require("./models/User"); // Model Pengguna

// Buat grup baru
router.post("/api/groups", async (req, res) => {
const { groupName, members } = req.body;
try {
const group = new Group({ groupName, members });
await group.save();
res.status(201).json({ message: "Group created successfully", group });
} catch (error) {
res.status(500).json({ error: "Failed to create group" });
}
});

// Tambahkan pesan ke grup
router.post("/api/groups/:groupId/messages", async (req, res) => {
const { groupId } = req.params;
const { sender, content } = req.body;
try {
const group = await Group.findById(groupId);
group.messages.push({ sender, content });
await group.save();
res.status(200).json({ message: "Message sent", group });
} catch (error) {
res.status(500).json({ error: "Failed to send message" });
}
});

// Ambil pesan grup
router.get("/api/groups/:groupId/messages", async (req, res) => {
const { groupId } = req.params;
try {
const group = await Group.findById(groupId).populate("messages.sender", "username");
res.status(200).json({ messages: group.messages });
} catch (error) {
res.status(500).json({ error: "Failed to fetch messages" });
}
});

module.exports = router;
16 changes: 16 additions & 0 deletions ebuddy/backend/loging.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const mongoose = require("mongoose");

const GroupSchema = new mongoose.Schema({
groupName: { type: String, required: true },
members: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }], // User IDs
messages: [
{
sender: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
content: String,
timestamp: { type: Date, default: Date.now },
},
],
});

const Group = mongoose.model("Group", GroupSchema);
module.exports = Group;
14 changes: 14 additions & 0 deletions ebuddy/backend/pagination.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
router.get("/api/groups/:groupId/messages", async (req, res) => {
const { groupId } = req.params;
const { page = 1, limit = 10 } = req.query; // Default 10 pesan per halaman
try {
const group = await Group.findById(groupId)
.populate("messages.sender", "username")
.skip((page - 1) * limit)
.limit(parseInt(limit));
res.status(200).json({ messages: group.messages });
} catch (error) {
res.status(500).json({ error: "Failed to fetch messages" });
}
});

12 changes: 12 additions & 0 deletions ebuddy/backend/protectAPI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const authenticateToken = (req, res, next) => {
const token = req.header("Authorization");
if (!token) return res.status(401).json({ error: "Access denied" });
try {
const verified = jwt.verify(token, process.env.JWT_SECRET);
req.user = verified;
next();
} catch (error) {
res.status(400).json({ error: "Invalid token" });
}
};

15 changes: 15 additions & 0 deletions ebuddy/backend/signal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
io.on("connection", (socket) => {
console.log("User connected for WebRTC: " + socket.id);

// Meneruskan pesan signaling
socket.on("signal", (data) => {
const { to, from, signal } = data;
io.to(to).emit("signal", { from, signal });
});

socket.on("join_call", (room) => {
socket.join(room);
socket.broadcast.to(room).emit("user-joined", socket.id);
});
});

13 changes: 13 additions & 0 deletions ebuddy/logging & monitoring/logging_winston.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const winston = require("winston");

const logger = winston.createLogger({
level: "info",
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: "error.log", level: "error" }),
new winston.transports.File({ filename: "combined.log" }),
],
});

logger.info("This is an informational message");
logger.error("This is an error message");
9 changes: 9 additions & 0 deletions ebuddy/logging & monitoring/monitoring.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const client = require("prom-client");
const collectDefaultMetrics = client.collectDefaultMetrics;

collectDefaultMetrics(); // Metrik default

app.get("/metrics", async (req, res) => {
res.set("Content-Type", client.register.contentType);
res.end(await client.register.metrics());
});
10 changes: 10 additions & 0 deletions ebuddy/logging & monitoring/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const mongoose = require("mongoose");

mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then(() => {
console.log("Connected to MongoDB Atlas");
}).catch((err) => {
console.error("Database connection error:", err);
});
14 changes: 14 additions & 0 deletions ebuddy/test/Jest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const request = require("supertest");
const app = require("./app"); // Import aplikasi Express.js

describe("User Authentication API", () => {
test("Should register a new user", async () => {
const response = await request(app).post("/api/register").send({
username: "testuser",
email: "[email protected]",
password: "password123",
});
expect(response.statusCode).toBe(201);
expect(response.body.message).toBe("User registered successfully");
});
});
14 changes: 14 additions & 0 deletions ebuddy/test/cypres.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
describe("Chat Application", () => {
it("Should allow user to send and receive messages", () => {
cy.visit("http://localhost:3000");
cy.get("input[name='email']").type("[email protected]");
cy.get("input[name='password']").type("password123");
cy.get("button[type='submit']").click();

cy.get("input[name='message']").type("Hello, World!");
cy.get("button[type='send']").click();

cy.contains("Hello, World!");
});
});

7 changes: 7 additions & 0 deletions ebuddy/test/load.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import http from "k6/http";
import { sleep } from "k6";

export default function () {
http.get("http://localhost:3000/api/messages");
sleep(1);
}
12 changes: 12 additions & 0 deletions ebuddy/test/turn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const peer = new Peer({
initiator: true,
trickle: false,
config: {
iceServers: [
{ urls: "stun:stun.l.google.com:19302" }, // STUN Server
{ urls: "turn:your-turn-server.com:3478", username: "user", credential: "password" }, // TURN Server
],
},
stream,
});

38 changes: 38 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import js from '@eslint/js'
import globals from 'globals'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'

export default [
{ ignores: ['dist'] },
{
files: ['**/*.{js,jsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parserOptions: {
ecmaVersion: 'latest',
ecmaFeatures: { jsx: true },
sourceType: 'module',
},
},
settings: { react: { version: '18.3' } },
plugins: {
react,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...js.configs.recommended.rules,
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
...reactHooks.configs.recommended.rules,
'react/jsx-no-target-blank': 'off',
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
]
Loading

0 comments on commit 045fd03

Please sign in to comment.