From ab83f60b9741e9d5977f7eff90be68376533cd02 Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Sat, 18 Jan 2025 10:35:36 +0330 Subject: [PATCH 1/5] add default mail port to the example file --- .example.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.example.env b/.example.env index 90564f68..4fd036db 100644 --- a/.example.env +++ b/.example.env @@ -65,7 +65,7 @@ CUSTOM_DOMAIN_USE_HTTPS=false # More info on the configuration on http://nodemailer.com/. MAIL_ENABLED=false MAIL_HOST= -MAIL_PORT= +MAIL_PORT=587 MAIL_SECURE=true MAIL_USER= MAIL_FROM= From fc265ef22154000dab3ad7a6946045c564484ce9 Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Sat, 18 Jan 2025 10:37:26 +0330 Subject: [PATCH 2/5] make sure jwt secret is not empty --- server/env.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/env.js b/server/env.js index 6eb95475..66f6db77 100644 --- a/server/env.js +++ b/server/env.js @@ -15,6 +15,11 @@ if (process.env.LINK_CUSTOM_ALPHABET === "") { delete process.env.LINK_CUSTOM_ALPHABET; } +// make sure jwt secret is not empty +if (process.env.JWT_SECRET === "") { + delete process.env.JWT_SECRET; +} + const env = cleanEnv(process.env, { PORT: num({ default: 3000 }), SITE_NAME: str({ example: "Kutt", default: "Kutt" }), From de103423e3a30d1d21528c12e59cfd5a584636a5 Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Sat, 18 Jan 2025 12:49:58 +0330 Subject: [PATCH 3/5] fix filtering table rows on sqlite and mysql --- server/knex.js | 2 ++ server/queries/domain.queries.js | 15 +++++++++------ server/queries/link.queries.js | 32 ++++++++++++++++---------------- server/queries/user.queries.js | 4 ++-- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/server/knex.js b/server/knex.js index f838f346..9cc39a79 100644 --- a/server/knex.js +++ b/server/knex.js @@ -28,4 +28,6 @@ db.isPostgres = isPostgres; db.isSQLite = isSQLite; db.isMySQL = isMySQL; +db.compatibleILIKE = isPostgres ? "andWhereILike" : "andWhereLike"; + module.exports = db; diff --git a/server/queries/domain.queries.js b/server/queries/domain.queries.js index dc60ab9c..d09689ce 100644 --- a/server/queries/domain.queries.js +++ b/server/queries/domain.queries.js @@ -142,16 +142,16 @@ async function getAdmin(match, params) { if (params?.user) { const id = parseInt(params?.user); if (Number.isNaN(id)) { - query.andWhereILike("users.email", "%" + params.user + "%"); + query[knex.compatibleILIKE]("users.email", "%" + params.user + "%"); } else { query.andWhere("domains.user_id", id); } } if (params?.search) { - query.andWhereRaw( - "concat_ws(' ', domains.address, domains.homepage) ILIKE '%' || ? || '%'", - [params.search] + query[knex.compatibleILIKE]( + knex.raw("concat_ws(' ', domains.address, domains.homepage)"), + "%" + params.search + "%" ); } @@ -180,14 +180,17 @@ async function totalAdmin(match, params) { if (params?.user) { const id = parseInt(params?.user); if (Number.isNaN(id)) { - query.andWhereILike("users.email", "%" + params.user + "%"); + query[knex.compatibleILIKE]("users.email", "%" + params.user + "%"); } else { query.andWhere("domains.user_id", id); } } if (params?.search) { - query.andWhereILike("domains.address", "%" + params.search + "%"); + query[knex.compatibleILIKE]( + knex.raw("concat_ws(' ', domains.address, domains.homepage)"), + "%" + params.search + "%" + ); } if (params?.links !== undefined) { diff --git a/server/queries/link.queries.js b/server/queries/link.queries.js index 4fddd621..543b67f6 100644 --- a/server/queries/link.queries.js +++ b/server/queries/link.queries.js @@ -64,9 +64,9 @@ async function total(match, params) { }); if (params?.search) { - query.andWhereRaw( - "concat_ws(' ', description, links.address, target, domains.address) ILIKE '%' || ? || '%'", - [params.search] + query[knex.compatibleILIKE]( + knex.raw("concat_ws(' ', description, links.address, target, domains.address)"), + "%" + params.search + "%" ); } query.leftJoin("domains", "links.domain_id", "domains.id"); @@ -87,21 +87,21 @@ async function totalAdmin(match, params) { if (params?.user) { const id = parseInt(params?.user); if (Number.isNaN(id)) { - query.andWhereILike("users.email", "%" + params.user + "%"); + query[knex.compatibleILIKE]("users.email", "%" + params.user + "%"); } else { query.andWhere("links.user_id", params.user); } } if (params?.search) { - query.andWhereRaw( - "concat_ws(' ', description, links.address, target) ILIKE '%' || ? || '%'", - [params.search] + query[knex.compatibleILIKE]( + knex.raw("concat_ws(' ', description, links.address, target)"), + "%" + params.search + "%" ); } if (params?.domain) { - query.andWhereRaw("domains.address ILIKE '%' || ? || '%'", [params.domain]); + query[knex.compatibleILIKE]("domains.address", "%" + params.domain + "%"); } query.leftJoin("domains", "links.domain_id", "domains.id"); @@ -122,9 +122,9 @@ async function get(match, params) { .orderBy("links.id", "desc"); if (params?.search) { - query.andWhereRaw( - "concat_ws(' ', description, links.address, target, domains.address) ILIKE '%' || ? || '%'", - [params.search] + query[knex.compatibleILIKE]( + knex.raw("concat_ws(' ', description, links.address, target, domains.address)"), + "%" + params.search + "%" ); } @@ -148,21 +148,21 @@ async function getAdmin(match, params) { if (params?.user) { const id = parseInt(params?.user); if (Number.isNaN(id)) { - query.andWhereILike("users.email", "%" + params.user + "%"); + query[knex.compatibleILIKE]("users.email", "%" + params.user + "%"); } else { query.andWhere("links.user_id", params.user); } } if (params?.search) { - query.andWhereRaw( - "concat_ws(' ', description, links.address, target) ILIKE '%' || ? || '%'", - [params.search] + query[knex.compatibleILIKE]( + knex.raw("concat_ws(' ', description, links.address, target)"), + "%" + params.search + "%" ); } if (params?.domain) { - query.andWhereRaw("domains.address ILIKE '%' || ? || '%'", [params.domain]); + query[knex.compatibleILIKE]("domains.address", "%" + params.domain + "%"); } query.leftJoin("domains", "links.domain_id", "domains.id"); diff --git a/server/queries/user.queries.js b/server/queries/user.queries.js index e56d99d5..cd056826 100644 --- a/server/queries/user.queries.js +++ b/server/queries/user.queries.js @@ -144,7 +144,7 @@ async function getAdmin(match, params) { if (params?.search) { const id = parseInt(params?.search); if (Number.isNaN(id)) { - query.andWhereILike("users.email", "%" + params?.search + "%"); + query[knex.compatibleILIKE]("users.email", "%" + params?.search + "%"); } else { query.andWhere("users.id", params?.search); } @@ -186,7 +186,7 @@ async function totalAdmin(match, params) { if (params?.search) { const id = parseInt(params?.search); if (Number.isNaN(id)) { - query.andWhereILike("users.email", "%" + params?.search + "%"); + query[knex.compatibleILIKE]("users.email", "%" + params?.search + "%"); } else { query.andWhere("users.id", params?.search); } From 876d12fc9dd9ab7d3128ce852043d7f99fdafcab Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Sat, 18 Jan 2025 12:56:27 +0330 Subject: [PATCH 4/5] use count(*) instead of count(id) since it's slightly faster --- server/queries/domain.queries.js | 6 +++--- server/queries/link.queries.js | 4 ++-- server/queries/user.queries.js | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/server/queries/domain.queries.js b/server/queries/domain.queries.js index d09689ce..d4d15674 100644 --- a/server/queries/domain.queries.js +++ b/server/queries/domain.queries.js @@ -160,7 +160,7 @@ async function getAdmin(match, params) { } query.leftJoin( - knex("links").select("domain_id").count("id as links_count").groupBy("domain_id").as("l"), + knex("links").select("domain_id").count("* as links_count").groupBy("domain_id").as("l"), "domains.id", "l.domain_id" ); @@ -195,7 +195,7 @@ async function totalAdmin(match, params) { if (params?.links !== undefined) { query.leftJoin( - knex("links").select("domain_id").count("id as links_count").groupBy("domain_id").as("l"), + knex("links").select("domain_id").count("* as links_count").groupBy("domain_id").as("l"), "domains.id", "l.domain_id" ); @@ -203,7 +203,7 @@ async function totalAdmin(match, params) { } query.leftJoin("users", "domains.user_id", "users.id"); - query.count("domains.id as count"); + query.count("* as count"); const [{ count }] = await query; diff --git a/server/queries/link.queries.js b/server/queries/link.queries.js index 543b67f6..f94f59cd 100644 --- a/server/queries/link.queries.js +++ b/server/queries/link.queries.js @@ -70,7 +70,7 @@ async function total(match, params) { ); } query.leftJoin("domains", "links.domain_id", "domains.id"); - query.count("links.id as count"); + query.count("* as count"); const [{ count }] = await query; @@ -106,7 +106,7 @@ async function totalAdmin(match, params) { query.leftJoin("domains", "links.domain_id", "domains.id"); query.leftJoin("users", "links.user_id", "users.id"); - query.count("links.id as count"); + query.count("* as count"); const [{ count }] = await query; diff --git a/server/queries/user.queries.js b/server/queries/user.queries.js index cd056826..936be47b 100644 --- a/server/queries/user.queries.js +++ b/server/queries/user.queries.js @@ -169,7 +169,7 @@ async function getAdmin(match, params) { "d.user_id" ) query.leftJoin( - knex("links").select("user_id").count("id as links_count").groupBy("user_id").as("l"), + knex("links").select("user_id").count("* as links_count").groupBy("user_id").as("l"), "users.id", "l.user_id" ); @@ -179,7 +179,7 @@ async function getAdmin(match, params) { async function totalAdmin(match, params) { const query = knex("users") - .count("users.id as count") + .count("* as count") .fromRaw('users') .where(normalizeMatch(match)); @@ -209,13 +209,13 @@ async function totalAdmin(match, params) { if (params?.links !== undefined) { query.andWhere("links", params?.links ? "is not" : "is", null); query.leftJoin( - knex("links").select("user_id").count("id as links").groupBy("user_id").as("l"), + knex("links").select("user_id").count("* as links").groupBy("user_id").as("l"), "users.id", "l.user_id" ); } - const [{count}] = await query; + const [{ count }] = await query; return typeof count === "number" ? count : parseInt(count); } From 8c4d92e373b6290735300adfff3ebd8cd38a786d Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Sat, 18 Jan 2025 12:56:32 +0330 Subject: [PATCH 5/5] 3.1.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8333acf0..0d4c63b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "kutt", - "version": "3.1.0", + "version": "3.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "kutt", - "version": "3.1.0", + "version": "3.1.1", "license": "MIT", "dependencies": { "bcryptjs": "2.4.3", diff --git a/package.json b/package.json index a9284005..f8d44bc2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kutt", - "version": "3.1.0", + "version": "3.1.1", "description": "Modern URL shortener.", "main": "./server/server.js", "scripts": {