Skip to content

Commit 5a68d5d

Browse files
committed
fix(app.js): add validation for invalid URL and return appropriate error response
fix(app.js): handle case when DB_JSON_PATH is not found and return appropriate error response fix(app.js): handle case when db is not found in MongoDB and return appropriate error response fix(app.js): add validation for custom code already existing and return appropriate error response fix(app.js): redirect to error page if shorten response does not contain shorten data feat(app.js): add support for custom_code parameter to allow users to specify their own short code fix(app.js): fix indentation in console.log statement feat(package.json): update version to 1.0.7 feat(public/index.html): add script to display error message if present in URL parameters
1 parent bddbc43 commit 5a68d5d

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

app.js

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,28 @@ function generateCode() {
4848
return Date.now().toString(16) + hex;
4949
}
5050

51-
async function shorten(url, password) {
51+
async function shorten(url, password, custom) {
5252
let data = {}
53+
let regex = /^(http|https):\/\/[^\s/$.?#].[^\s]*$/;
54+
55+
if (!regex.test(url)) return { status: 400, data: {}, message: "Error: Invalid URL" };
5356

5457
if (isJSON) {
5558
if (!config.DB_JSON_PATH) {
5659
console.log("Error: DB_JSON_PATH not found");
57-
return res.status(500).send("Error: DB_JSON_PATH not found");
60+
return { status: 500, data: {}, message: "Error: DB_JSON_PATH not found" }
5861
} else {
5962
if (!fs.existsSync(config.DB_JSON_PATH)) fs.writeFileSync(config.DB_JSON_PATH, JSON.stringify({}));
6063
}
6164

6265
let db = JSON.parse(fs.readFileSync(config.DB_JSON_PATH));
63-
let code = generateCode();
66+
let code = "";
67+
if (custom) {
68+
if (db[custom]) return { status: 400, data: {}, message: "Error: Code already exists" };
69+
code = custom;
70+
} else {
71+
code = generateCode();
72+
}
6473

6574
if (password) {
6675
let hashPass = SHA256(password).toString();
@@ -72,16 +81,21 @@ async function shorten(url, password) {
7281
fs.writeFileSync(config.DB_JSON_PATH, JSON.stringify(db));
7382
data = { status: 200, data: { original: url, shorten: `${config.DOMAIN}/s/${code}` } };
7483
} else if (isMongoDB) {
75-
let code = generateCode();
76-
7784
await client.connect();
7885
let db = client.db(dbName);
7986
if (!db) {
8087
console.log("Error: db not found");
81-
return;
88+
return { status: 500, data: {}, message: "Error: DB not found." }
8289
}
8390
let collection = db.collection('links');
8491

92+
let code = generateCode();
93+
if (custom) {
94+
let filtered = await collection.find({code: custom}).toArray();
95+
if (filtered.length > 0) return { status: 400, data: {}, message: "Error: Code already exists" };
96+
code = custom;
97+
}
98+
8599
if (password) {
86100
let hashPass = SHA256(password).toString();
87101
await collection.insertOne({link: url, code: code, password: hashPass});
@@ -96,12 +110,13 @@ async function shorten(url, password) {
96110
}
97111

98112
app.post('/api/form_shorten', multer().none(), async (req, res) => {
99-
let resp = await shorten(req.body.link, req.body.password);
113+
let resp = await shorten(req.body.link, req.body.password, req.body.custom_code);
114+
if (!resp.data.shorten) return res.redirect(`/?error=${Base64.encode(resp.message)}`);
100115
res.redirect(`/generated?link=${Base64.encode(resp.data.shorten)}`);
101116
});
102117

103118
app.post('/api/shorten', multer().none(), async (req, res) => {
104-
res.json(await shorten(req.body.link, req.body.password));
119+
res.json(await shorten(req.body.link, req.body.password, req.body.custom_code));
105120
});
106121

107122
app.get("/s/:code", async (req, res) => {
@@ -288,5 +303,5 @@ app.listen(process.env.PORT || config.PORT, async () => {
288303
}
289304

290305
const port = process.env.PORT || config.PORT;
291-
console.log(`Quecto listening on port ${port}!`);
306+
console.log(`Quecto listening on port ${port}!`);
292307
});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "quecto",
3-
"version": "1.0.5g",
3+
"version": "1.0.7",
44
"description": "",
55
"main": "index.js",
66
"scripts": {

public/index.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,25 @@
55
<title>Quecto</title>
66

77
<link rel="stylesheet" href="/public/style.css">
8+
<script src="https://cdn.jsdelivr.net/npm/js-base64@3.7.5/base64.min.js"></script>
89
</head>
910
<body>
1011
<form action="/api/form_shorten" method="post">
1112
<div class="content">
1213
<input type="text" name="link" placeholder="Link" required>
1314
<input type="password" name="password" placeholder="Password"> <br>
15+
<input type="text" name="custom_code" placeholder="Custom Short Code"> <br>
1416
<input type="submit" value="Shorten">
1517
</div>
1618
</form>
19+
20+
<script>
21+
window.onload = () => {
22+
const searchParams = new URLSearchParams(window.location.search);
23+
const error = searchParams.get('error');
24+
if (!error) return;
25+
alert(Base64.decode(error));
26+
}
27+
</script>
1728
</body>
1829
</html>

0 commit comments

Comments
 (0)