You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
3.6 KiB

11 months ago
  1. const path = require("path");
  2. const fs = require("fs");
  3. const { getType } = require("mime");
  4. const { v4 } = require("uuid");
  5. const { SystemSettings } = require("../../models/systemSettings");
  6. const { normalizePath, isWithin } = require(".");
  7. const LOGO_FILENAME = "anything-llm.png";
  8. const LOGO_FILENAME_DARK = "anything-llm-dark.png";
  9. /**
  10. * Checks if the filename is the default logo filename for dark or light mode.
  11. * @param {string} filename - The filename to check.
  12. * @returns {boolean} Whether the filename is the default logo filename.
  13. */
  14. function isDefaultFilename(filename) {
  15. return [LOGO_FILENAME, LOGO_FILENAME_DARK].includes(filename);
  16. }
  17. function validFilename(newFilename = "") {
  18. return !isDefaultFilename(newFilename);
  19. }
  20. /**
  21. * Shows the logo for the current theme. In dark mode, it shows the light logo
  22. * and vice versa.
  23. * @param {boolean} darkMode - Whether the logo should be for dark mode.
  24. * @returns {string} The filename of the logo.
  25. */
  26. function getDefaultFilename(darkMode = true) {
  27. return darkMode ? LOGO_FILENAME : LOGO_FILENAME_DARK;
  28. }
  29. async function determineLogoFilepath(defaultFilename = LOGO_FILENAME) {
  30. const currentLogoFilename = await SystemSettings.currentLogoFilename();
  31. const basePath = process.env.STORAGE_DIR
  32. ? path.join(process.env.STORAGE_DIR, "assets")
  33. : path.join(__dirname, "../../storage/assets");
  34. const defaultFilepath = path.join(basePath, defaultFilename);
  35. if (currentLogoFilename && validFilename(currentLogoFilename)) {
  36. customLogoPath = path.join(basePath, normalizePath(currentLogoFilename));
  37. if (!isWithin(path.resolve(basePath), path.resolve(customLogoPath)))
  38. return defaultFilepath;
  39. return fs.existsSync(customLogoPath) ? customLogoPath : defaultFilepath;
  40. }
  41. return defaultFilepath;
  42. }
  43. function fetchLogo(logoPath) {
  44. if (!fs.existsSync(logoPath)) {
  45. return {
  46. found: false,
  47. buffer: null,
  48. size: 0,
  49. mime: "none/none",
  50. };
  51. }
  52. const mime = getType(logoPath);
  53. const buffer = fs.readFileSync(logoPath);
  54. return {
  55. found: true,
  56. buffer,
  57. size: buffer.length,
  58. mime,
  59. };
  60. }
  61. async function renameLogoFile(originalFilename = null) {
  62. const extname = path.extname(originalFilename) || ".png";
  63. const newFilename = `${v4()}${extname}`;
  64. const assetsDirectory = process.env.STORAGE_DIR
  65. ? path.join(process.env.STORAGE_DIR, "assets")
  66. : path.join(__dirname, `../../storage/assets`);
  67. const originalFilepath = path.join(
  68. assetsDirectory,
  69. normalizePath(originalFilename)
  70. );
  71. if (!isWithin(path.resolve(assetsDirectory), path.resolve(originalFilepath)))
  72. throw new Error("Invalid file path.");
  73. // The output always uses a random filename.
  74. const outputFilepath = process.env.STORAGE_DIR
  75. ? path.join(process.env.STORAGE_DIR, "assets", normalizePath(newFilename))
  76. : path.join(__dirname, `../../storage/assets`, normalizePath(newFilename));
  77. fs.renameSync(originalFilepath, outputFilepath);
  78. return newFilename;
  79. }
  80. async function removeCustomLogo(logoFilename = LOGO_FILENAME) {
  81. if (!logoFilename || !validFilename(logoFilename)) return false;
  82. const assetsDirectory = process.env.STORAGE_DIR
  83. ? path.join(process.env.STORAGE_DIR, "assets")
  84. : path.join(__dirname, `../../storage/assets`);
  85. const logoPath = path.join(assetsDirectory, normalizePath(logoFilename));
  86. if (!isWithin(path.resolve(assetsDirectory), path.resolve(logoPath)))
  87. throw new Error("Invalid file path.");
  88. if (fs.existsSync(logoPath)) fs.unlinkSync(logoPath);
  89. return true;
  90. }
  91. module.exports = {
  92. fetchLogo,
  93. renameLogoFile,
  94. removeCustomLogo,
  95. validFilename,
  96. getDefaultFilename,
  97. determineLogoFilepath,
  98. isDefaultFilename,
  99. LOGO_FILENAME,
  100. };