From 1e01e10459e1bd53b860059d28910937343ef039 Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Wed, 15 Jan 2025 11:45:53 +0330 Subject: [PATCH 01/22] add customization --- .gitignore | 2 ++ custom/.gitkeep | 3 +++ package.json | 2 +- server/handlers/locals.handler.js | 1 + server/server.js | 10 +++++++++- server/utils/utils.js | 29 ++++++++++++++++++++++++++++- server/views/layout.hbs | 3 +++ 7 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 custom/.gitkeep diff --git a/.gitignore b/.gitignore index 20f118b70..bac50cd17 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ docs/api/static **/.DS_Store db/* !db/.gitkeep +custom/* +!custom/.gitkeep diff --git a/custom/.gitkeep b/custom/.gitkeep new file mode 100644 index 000000000..110e92f6c --- /dev/null +++ b/custom/.gitkeep @@ -0,0 +1,3 @@ +# keep this folder in git +# put supported customization files for styles and such +# if you're using docker make sure to mount this folder \ No newline at end of file diff --git a/package.json b/package.json index f06045a62..ba4fca19a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Modern URL shortener.", "main": "./server/server.js", "scripts": { - "dev": "cross-env NODE_ENV=development node --watch-path=./server server/server.js", + "dev": "cross-env NODE_ENV=development node --watch-path=./server --watch-path=./custom server/server.js", "start": "cross-env NODE_ENV=production node server/server.js", "migrate": "knex migrate:latest", "migrate:make": "knex migrate:make", diff --git a/server/handlers/locals.handler.js b/server/handlers/locals.handler.js index 17a4655b8..7b1b4ab25 100644 --- a/server/handlers/locals.handler.js +++ b/server/handlers/locals.handler.js @@ -29,6 +29,7 @@ function config(req, res, next) { res.locals.disallow_registration = env.DISALLOW_REGISTRATION; res.locals.mail_enabled = env.MAIL_ENABLED; res.locals.report_email = env.REPORT_EMAIL; + res.locals.custom_styles = utils.getCustomCSSFileNames(); next(); } diff --git a/server/server.js b/server/server.js index e353500ab..abb174f95 100644 --- a/server/server.js +++ b/server/server.js @@ -40,6 +40,10 @@ app.use(helmet({ contentSecurityPolicy: false })); app.use(cookieParser()); app.use(express.json()); app.use(express.urlencoded({ extended: true })); + +// serve static +app.use("/images", express.static("custom/images")); +app.use("/css", express.static("custom/css", { extensions: ["css"] })); app.use(express.static("static")); app.use(passport.initialize()); @@ -47,8 +51,12 @@ app.use(locals.isHTML); app.use(locals.config); // template engine / serve html + app.set("view engine", "hbs"); -app.set("views", path.join(__dirname, "views")); +app.set("views", [ + path.join(__dirname, "../custom/views"), + path.join(__dirname, "views"), +]); utils.registerHandlebarsHelpers(); // if is custom domain, redirect to the set homepage diff --git a/server/utils/utils.js b/server/utils/utils.js index 25285cd89..c47495301 100644 --- a/server/utils/utils.js +++ b/server/utils/utils.js @@ -1,7 +1,8 @@ const { differenceInDays, differenceInHours, differenceInMonths, differenceInMilliseconds, addDays, subHours, subDays, subMonths, subYears, format } = require("date-fns"); const { customAlphabet } = require("nanoid"); const JWT = require("jsonwebtoken"); -const path = require("path"); +const path = require("node:path"); +const fs = require("node:fs"); const hbs = require("hbs"); const ms = require("ms"); @@ -360,6 +361,31 @@ function registerHandlebarsHelpers() { return val; }); hbs.registerPartials(path.join(__dirname, "../views/partials"), function (err) {}); + const customPartialsPath = path.join(__dirname, "../../custom/views/partials"); + const customPartialsExist = fs.existsSync(customPartialsPath); + if (customPartialsExist) { + hbs.registerPartials(customPartialsPath, function (err) {}); + } +} + +// grab custom styles file name from the custom/css folder +const custom_css_file_names = []; +const customCSSPath = path.join(__dirname, "../../custom/css"); +const customCSSExists = fs.existsSync(customCSSPath); +if (customCSSExists) { + fs.readdir(customCSSPath, function(error, files) { + if (error) { + console.warn("Could not read the custom CSS folder:", error); + } else { + files.forEach(function(file_name) { + custom_css_file_names.push(file_name); + }); + } + }) +} + +function getCustomCSSFileNames() { + return custom_css_file_names; } module.exports = { @@ -368,6 +394,7 @@ module.exports = { dateToUTC, deleteCurrentToken, generateId, + getCustomCSSFileNames, getDifferenceFunction, getInitStats, getShortURL, diff --git a/server/views/layout.hbs b/server/views/layout.hbs index 8c22ba1d2..814339cc6 100644 --- a/server/views/layout.hbs +++ b/server/views/layout.hbs @@ -24,6 +24,9 @@ {{site_name}} | {{title}} + {{#each custom_styles}} + + {{/each}} {{{block "stylesheets"}}} From 2345a391f8b370920fb71c08f46f0208bb2fca7f Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Wed, 15 Jan 2025 11:46:28 +0330 Subject: [PATCH 02/22] change docker image work directory from /kutt to /app --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f56c48fb3..2d9cbc1b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ FROM node:22-alpine ENV NODE_ENV=production # set working directory. -WORKDIR /kutt +WORKDIR /app # download dependencies while using Docker's caching RUN --mount=type=bind,source=package.json,target=package.json \ From b596f7e8509080fe21144b0bbd08bd9dbac12bb3 Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Wed, 15 Jan 2025 11:48:53 +0330 Subject: [PATCH 03/22] change sqlite db data path for sqlite-redis docker composition --- docker-compose.sqlite-redis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.sqlite-redis.yml b/docker-compose.sqlite-redis.yml index 6b2d8bd11..667c1ba76 100644 --- a/docker-compose.sqlite-redis.yml +++ b/docker-compose.sqlite-redis.yml @@ -3,7 +3,7 @@ services: build: context: . volumes: - - db-data:/var/lib/kutt + - db_data_sqlite:/var/lib/kutt environment: DB_FILENAME: "/var/lib/kutt/data.sqlite" REDIS_ENABLED: true @@ -20,4 +20,4 @@ services: expose: - 6379 volumes: - db-data: \ No newline at end of file + db_data_sqlite: \ No newline at end of file From f4a59d4b14eb00a92ebba6ff9388ebcccffcf124 Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Wed, 15 Jan 2025 11:49:30 +0330 Subject: [PATCH 04/22] add custom folder volume to docker compositions --- docker-compose.mariadb.yml | 5 ++++- docker-compose.postgres.yml | 5 ++++- docker-compose.sqlite-redis.yml | 4 +++- docker-compose.yml | 4 +++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docker-compose.mariadb.yml b/docker-compose.mariadb.yml index 96e11a0b1..5b0c68b57 100644 --- a/docker-compose.mariadb.yml +++ b/docker-compose.mariadb.yml @@ -2,6 +2,8 @@ services: server: build: context: . + volumes: + - custom:/app/custom environment: DB_CLIENT: mysql2 DB_HOST: mariadb @@ -39,4 +41,5 @@ services: expose: - 6379 volumes: - db_data_mariadb: \ No newline at end of file + db_data_mariadb: + custom: \ No newline at end of file diff --git a/docker-compose.postgres.yml b/docker-compose.postgres.yml index d41272680..fdd4b544d 100644 --- a/docker-compose.postgres.yml +++ b/docker-compose.postgres.yml @@ -2,6 +2,8 @@ services: server: build: context: . + volumes: + - custom:/app/custom environment: DB_CLIENT: pg DB_HOST: postgres @@ -37,4 +39,5 @@ services: expose: - 6379 volumes: - db_data_pg: \ No newline at end of file + db_data_pg: + custom: \ No newline at end of file diff --git a/docker-compose.sqlite-redis.yml b/docker-compose.sqlite-redis.yml index 667c1ba76..4cc4af164 100644 --- a/docker-compose.sqlite-redis.yml +++ b/docker-compose.sqlite-redis.yml @@ -4,6 +4,7 @@ services: context: . volumes: - db_data_sqlite:/var/lib/kutt + - custom:/app/custom environment: DB_FILENAME: "/var/lib/kutt/data.sqlite" REDIS_ENABLED: true @@ -20,4 +21,5 @@ services: expose: - 6379 volumes: - db_data_sqlite: \ No newline at end of file + db_data_sqlite: + custom: \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 01e7fe632..2983e44da 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,9 +4,11 @@ services: context: . volumes: - db_data_sqlite:/var/lib/kutt + - custom:/app/custom environment: DB_FILENAME: "/var/lib/kutt/data.sqlite" ports: - 3000:3000 volumes: - db_data_sqlite: \ No newline at end of file + db_data_sqlite: + custom: \ No newline at end of file From b4849ee7371d702a31c0fbb53f0e7a086b56a3f5 Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Wed, 15 Jan 2025 11:49:47 +0330 Subject: [PATCH 05/22] change default db port variable for postgres docker composition --- docker-compose.postgres.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.postgres.yml b/docker-compose.postgres.yml index fdd4b544d..d89a11bec 100644 --- a/docker-compose.postgres.yml +++ b/docker-compose.postgres.yml @@ -7,6 +7,7 @@ services: environment: DB_CLIENT: pg DB_HOST: postgres + DB_PORT: 5432 REDIS_ENABLED: true REDIS_HOST: redis REDIS_PORT: 6379 From 602ba45cf6c99934c9d20a792c95327eee53c736 Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Wed, 15 Jan 2025 11:49:55 +0330 Subject: [PATCH 06/22] removed unused images --- static/images/icons/icon-128x128.png | Bin 5188 -> 0 bytes static/images/icons/icon-144x144.png | Bin 5825 -> 0 bytes static/images/icons/icon-152x152.png | Bin 6142 -> 0 bytes static/images/icons/icon-192x192.png | Bin 7823 -> 0 bytes static/images/icons/icon-384x384.png | Bin 17463 -> 0 bytes static/images/icons/icon-512x512.png | Bin 24018 -> 0 bytes static/images/icons/icon-72x72.png | Bin 2811 -> 0 bytes static/images/icons/icon-96x96.png | Bin 3890 -> 0 bytes static/images/kutt.svg | 14 -------------- 9 files changed, 14 deletions(-) delete mode 100644 static/images/icons/icon-128x128.png delete mode 100644 static/images/icons/icon-144x144.png delete mode 100644 static/images/icons/icon-152x152.png delete mode 100644 static/images/icons/icon-192x192.png delete mode 100644 static/images/icons/icon-384x384.png delete mode 100644 static/images/icons/icon-512x512.png delete mode 100644 static/images/icons/icon-72x72.png delete mode 100644 static/images/icons/icon-96x96.png delete mode 100644 static/images/kutt.svg diff --git a/static/images/icons/icon-128x128.png b/static/images/icons/icon-128x128.png deleted file mode 100644 index 14fd387fcf8cc80692fbef3ff532c931cb997175..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5188 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 Sx7dGQyu0n4?aFPa^#1|32&x|d diff --git a/static/images/icons/icon-384x384.png b/static/images/icons/icon-384x384.png deleted file mode 100644 index 486fb1fa8e8b9a96e05b3951571d8b72b29fd99e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17463 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 P00000NkvXXu0mjf)8nVz diff --git a/static/images/icons/icon-512x512.png b/static/images/icons/icon-512x512.png deleted file mode 100644 index b89fcb8fad6f0a17ebe84f384daeeba9bf7c0ce4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24018 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 diff --git a/static/images/icons/icon-96x96.png b/static/images/icons/icon-96x96.png deleted file mode 100644 index ba957eca8079da564ff0a35cd08e87fe8a1ee7d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3890 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 SO$Yh+8#UB7)+^E>h5ZMoLZ9#e diff --git a/static/images/kutt.svg b/static/images/kutt.svg deleted file mode 100644 index 2718b9aab..000000000 --- a/static/images/kutt.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - From 028b8a0e57f809a770496a79480e90a2db75c0a7 Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Wed, 15 Jan 2025 14:04:52 +0330 Subject: [PATCH 07/22] add custom alphabet for link address --- .example.env | 4 ++++ server/env.js | 6 ++++++ server/handlers/validators.handler.js | 4 ++-- server/utils/utils.js | 13 +++++++++---- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/.example.env b/.example.env index 0555dfbf1..cfe3605fa 100644 --- a/.example.env +++ b/.example.env @@ -26,6 +26,10 @@ DB_POOL_MAX=10 # Optional - Generated link length LINK_LENGTH=6 +# Optional - Alphabet used to generate custom addresses +# Default value omits o, O, 0, i, I, l, 1, and j to avoid confusion when reading the URL +LINK_CUSTOM_ALPHABET=abcdefghkmnpqrstuvwxyzABCDEFGHKLMNPQRSTUVWXYZ23456789 + # Optional - Redis host and port REDIS_ENABLED=false REDIS_HOST=127.0.0.1 diff --git a/server/env.js b/server/env.js index 8cdab403b..13190bf02 100644 --- a/server/env.js +++ b/server/env.js @@ -10,11 +10,17 @@ const supportedDBClients = [ "mysql2" ]; +// make sure custom alphabet is not empty +if (process.env.LINK_CUSTOM_ALPHABET === "") { + delete process.env.LINK_CUSTOM_ALPHABET; +} + const env = cleanEnv(process.env, { PORT: num({ default: 3000 }), SITE_NAME: str({ example: "Kutt", default: "Kutt" }), DEFAULT_DOMAIN: str({ example: "kutt.it", default: "localhost:3000" }), LINK_LENGTH: num({ default: 6 }), + LINK_CUSTOM_ALPHABET: str({ default: "abcdefghkmnpqrstuvwxyzABCDEFGHKLMNPQRSTUVWXYZ23456789" }), DB_CLIENT: str({ choices: supportedDBClients, default: "sqlite3" }), DB_FILENAME: str({ default: "db/data" }), DB_HOST: str({ default: "localhost" }), diff --git a/server/handlers/validators.handler.js b/server/handlers/validators.handler.js index bef3fe1d7..4ba29c6f3 100644 --- a/server/handlers/validators.handler.js +++ b/server/handlers/validators.handler.js @@ -45,7 +45,7 @@ const createLink = [ .trim() .isLength({ min: 1, max: 64 }) .withMessage("Custom URL length must be between 1 and 64.") - .custom(value => /^[a-zA-Z0-9-_]+$/g.test(value)) + .custom(value => utils.customAddressRegex.test(value) || utils.customAlphabetRegex.test(value)) .withMessage("Custom URL is not valid.") .custom(value => !utils.preservedURLs.some(url => url.toLowerCase() === value)) .withMessage("You can't use this custom URL."), @@ -120,7 +120,7 @@ const editLink = [ .trim() .isLength({ min: 1, max: 64 }) .withMessage("Custom URL length must be between 1 and 64.") - .custom(value => /^[a-zA-Z0-9-_]+$/g.test(value)) + .custom(value => utils.customAddressRegex.test(value) || utils.customAlphabetRegex.test(value)) .withMessage("Custom URL is not valid") .custom(value => !utils.preservedURLs.some(url => url.toLowerCase() === value)) .withMessage("You can't use this custom URL."), diff --git a/server/utils/utils.js b/server/utils/utils.js index c47495301..209537822 100644 --- a/server/utils/utils.js +++ b/server/utils/utils.js @@ -11,10 +11,7 @@ const knexUtils = require("./knex"); const knex = require("../knex"); const env = require("../env"); -const nanoid = customAlphabet( - "abcdefghkmnpqrstuvwxyzABCDEFGHKLMNPQRSTUVWXYZ23456789", - env.LINK_LENGTH -); +const nanoid = customAlphabet(env.LINK_CUSTOM_ALPHABET, env.LINK_LENGTH); class CustomError extends Error { constructor(message, statusCode, data) { @@ -27,6 +24,12 @@ class CustomError extends Error { const urlRegex = /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i; +const charsNeedEscapeInRegExp = ".$*+?()[]{}|^-"; +const customAlphabetEscaped = env.LINK_CUSTOM_ALPHABET + .split("").map(c => charsNeedEscapeInRegExp.includes(c) ? "\\" + c : c).join(""); +const customAlphabetRegex = new RegExp(`^[${customAlphabetEscaped}_-]+$`); +const customAddressRegex = new RegExp("^[a-zA-Z0-9-_]+$"); + function isAdmin(user) { return user.role === ROLES.ADMIN; } @@ -390,6 +393,8 @@ function getCustomCSSFileNames() { module.exports = { addProtocol, + customAddressRegex, + customAlphabetRegex, CustomError, dateToUTC, deleteCurrentToken, From 95909deab29919c5fc9dbe7a9ec6b7cd1447e83d Mon Sep 17 00:00:00 2001 From: Pouria Ezzati Date: Wed, 15 Jan 2025 14:05:08 +0330 Subject: [PATCH 08/22] fix showing empty domain when editing a link throws error --- server/views/partials/admin/links/edit.hbs | 2 +- server/views/partials/links/edit.hbs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/views/partials/admin/links/edit.hbs b/server/views/partials/admin/links/edit.hbs index 902797fbf..24198d6ee 100644 --- a/server/views/partials/admin/links/edit.hbs +++ b/server/views/partials/admin/links/edit.hbs @@ -25,7 +25,7 @@ {{#if errors.target}}

{{errors.target}}

{{/if}}