Skip to content

Commit bb9ccc9

Browse files
authored
Feat/social media platforms (#196)
* chore: this part works now wooohooo * chore: stash progress * chore: stash progress * chore: init message data models * feat: different socials * chore: blabsy ready for redesign * chore: add other socials
1 parent b235d28 commit bb9ccc9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3850
-0
lines changed

platforms/blabsy-api/package.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"name": "piqtique-api",
3+
"version": "1.0.0",
4+
"description": "Piqtique Social Media Platform API",
5+
"main": "src/index.ts",
6+
"scripts": {
7+
"start": "ts-node src/index.ts",
8+
"dev": "nodemon --exec ts-node src/index.ts",
9+
"build": "tsc",
10+
"typeorm": "typeorm-ts-node-commonjs",
11+
"migration:generate": "npm run typeorm migration:generate -- -d src/database/data-source.ts",
12+
"migration:run": "npm run typeorm migration:run -- -d src/database/data-source.ts",
13+
"migration:revert": "npm run typeorm migration:revert -- -d src/database/data-source.ts"
14+
},
15+
"dependencies": {
16+
"axios": "^1.6.7",
17+
"cors": "^2.8.5",
18+
"dotenv": "^16.4.5",
19+
"eventsource-polyfill": "^0.9.6",
20+
"express": "^4.18.2",
21+
"jsonwebtoken": "^9.0.2",
22+
"pg": "^8.11.3",
23+
"reflect-metadata": "^0.2.1",
24+
"typeorm": "^0.3.20",
25+
"uuid": "^9.0.1"
26+
},
27+
"devDependencies": {
28+
"@types/cors": "^2.8.17",
29+
"@types/express": "^4.17.21",
30+
"@types/jsonwebtoken": "^9.0.5",
31+
"@types/node": "^20.11.24",
32+
"@types/pg": "^8.11.2",
33+
"@types/uuid": "^9.0.8",
34+
"@typescript-eslint/eslint-plugin": "^7.0.1",
35+
"@typescript-eslint/parser": "^7.0.1",
36+
"eslint": "^8.56.0",
37+
"nodemon": "^3.0.3",
38+
"ts-node": "^10.9.2",
39+
"typescript": "^5.3.3"
40+
}
41+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { Request, Response } from "express";
2+
import { v4 as uuidv4 } from "uuid";
3+
import { UserService } from "../services/UserService";
4+
import { EventEmitter } from "events";
5+
export class AuthController {
6+
private userService: UserService;
7+
private eventEmitter: EventEmitter;
8+
9+
constructor() {
10+
this.userService = new UserService();
11+
this.eventEmitter = new EventEmitter();
12+
}
13+
14+
sseStream = async (req: Request, res: Response) => {
15+
const { id } = req.params;
16+
17+
// Set headers for SSE
18+
res.writeHead(200, {
19+
"Content-Type": "text/event-stream",
20+
"Cache-Control": "no-cache",
21+
Connection: "keep-alive",
22+
"Access-Control-Allow-Origin": "*",
23+
});
24+
25+
const handler = (data: any) => {
26+
res.write(`data: ${JSON.stringify(data)}\n\n`);
27+
};
28+
29+
this.eventEmitter.on(id, handler);
30+
31+
// Handle client disconnect
32+
req.on("close", () => {
33+
this.eventEmitter.off(id, handler);
34+
res.end();
35+
});
36+
37+
req.on("error", (error) => {
38+
console.error("SSE Error:", error);
39+
this.eventEmitter.off(id, handler);
40+
res.end();
41+
});
42+
};
43+
44+
getOffer = async (req: Request, res: Response) => {
45+
const url = new URL(
46+
"/api/auth",
47+
process.env.PUBLIC_BLABSY_BASE_URL,
48+
).toString();
49+
const session = uuidv4();
50+
const offer = `w3ds://auth?redirect=${url}&session=${session}&platform=blabsy`;
51+
res.json({ uri: offer });
52+
};
53+
54+
login = async (req: Request, res: Response) => {
55+
try {
56+
const { ename, session } = req.body;
57+
58+
if (!ename) {
59+
return res.status(400).json({ error: "ename is required" });
60+
}
61+
62+
const { user, token } =
63+
await this.userService.findOrCreateUser(ename);
64+
65+
const data = {
66+
user: {
67+
id: user.id,
68+
ename: user.ename,
69+
isVerified: user.isVerified,
70+
isPrivate: user.isPrivate,
71+
},
72+
token,
73+
};
74+
this.eventEmitter.emit(session, data);
75+
res.status(200).send();
76+
} catch (error) {
77+
console.error("Error during login:", error);
78+
res.status(500).json({ error: "Internal server error" });
79+
}
80+
};
81+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { Request, Response } from "express";
2+
import { CommentService } from "../services/CommentService";
3+
4+
export class CommentController {
5+
private commentService: CommentService;
6+
7+
constructor() {
8+
this.commentService = new CommentService();
9+
}
10+
11+
createComment = async (req: Request, res: Response) => {
12+
try {
13+
const { blabId, text } = req.body;
14+
const userId = req.user?.id;
15+
16+
if (!userId) {
17+
return res.status(401).json({ error: "Unauthorized" });
18+
}
19+
20+
const reply = await this.commentService.createComment(blabId, userId, text);
21+
res.status(201).json(reply);
22+
} catch (error) {
23+
console.error("Error creating reply:", error);
24+
res.status(500).json({ error: "Internal server error" });
25+
}
26+
};
27+
28+
getPostComments = async (req: Request, res: Response) => {
29+
try {
30+
const { blabId } = req.params;
31+
const replies = await this.commentService.getPostComments(blabId);
32+
res.json(replies);
33+
} catch (error) {
34+
console.error("Error fetching replies:", error);
35+
res.status(500).json({ error: "Internal server error" });
36+
}
37+
};
38+
39+
updateComment = async (req: Request, res: Response) => {
40+
try {
41+
const { id } = req.params;
42+
const { text } = req.body;
43+
const userId = req.user?.id;
44+
45+
if (!userId) {
46+
return res.status(401).json({ error: "Unauthorized" });
47+
}
48+
49+
const reply = await this.commentService.getCommentById(id);
50+
51+
if (!reply) {
52+
return res.status(404).json({ error: "Reply not found" });
53+
}
54+
55+
if (reply.creator.id !== userId) {
56+
return res.status(403).json({ error: "Forbidden" });
57+
}
58+
59+
const updatedReply = await this.commentService.updateComment(id, text);
60+
res.json(updatedReply);
61+
} catch (error) {
62+
console.error("Error updating reply:", error);
63+
res.status(500).json({ error: "Internal server error" });
64+
}
65+
};
66+
67+
deleteComment = async (req: Request, res: Response) => {
68+
try {
69+
const { id } = req.params;
70+
const userId = req.user?.id;
71+
72+
if (!userId) {
73+
return res.status(401).json({ error: "Unauthorized" });
74+
}
75+
76+
const reply = await this.commentService.getCommentById(id);
77+
78+
if (!reply) {
79+
return res.status(404).json({ error: "Reply not found" });
80+
}
81+
82+
if (reply.creator.id !== userId) {
83+
return res.status(403).json({ error: "Forbidden" });
84+
}
85+
86+
await this.commentService.deleteComment(id);
87+
res.status(204).send();
88+
} catch (error) {
89+
console.error("Error deleting reply:", error);
90+
res.status(500).json({ error: "Internal server error" });
91+
}
92+
};
93+
}

0 commit comments

Comments
 (0)