diff --git a/src/public/app/widgets/type_widgets/options/other/share_settings.ts b/src/public/app/widgets/type_widgets/options/other/share_settings.ts
index 199605082..abc540b49 100644
--- a/src/public/app/widgets/type_widgets/options/other/share_settings.ts
+++ b/src/public/app/widgets/type_widgets/options/other/share_settings.ts
@@ -2,44 +2,91 @@ import OptionsWidget from "../options_widget.js";
import options from "../../../../services/options.js";
import { t } from "../../../../services/i18n.js";
import type { OptionMap, OptionNames } from "../../../../../../services/options_interface.js";
+import searchService from "../../../../services/search.js";
const TPL = `
`;
export default class ShareSettingsOptions extends OptionsWidget {
+ private $shareRootCheck!: JQuery;
+ private $shareRootStatus!: JQuery;
+
doRender() {
this.$widget = $(TPL);
this.contentSized();
+ this.$shareRootCheck = this.$widget.find('.share-root-check');
+ this.$shareRootStatus = this.$widget.find('.share-root-status');
+
// Add change handlers for both checkboxes
- this.$widget.find('input[type="checkbox"]').on("change", () => this.save());
+ this.$widget.find('input[type="checkbox"]').on("change", (e: JQuery.ChangeEvent) => {
+ this.save();
+
+ // Show/hide share root status section based on redirectBareDomain checkbox
+ const target = e.target as HTMLInputElement;
+ if (target.name === 'redirectBareDomain') {
+ this.$shareRootCheck.toggle(target.checked);
+ if (target.checked) {
+ this.checkShareRoot();
+ }
+ }
+ });
+
+ // Add click handler for check share root button
+ this.$widget.find('.check-share-root').on("click", () => this.checkShareRoot());
}
async optionsLoaded(options: OptionMap) {
- this.$widget.find('input[name="redirectBareDomain"]').prop("checked", options.redirectBareDomain === "true");
+ const redirectBareDomain = options.redirectBareDomain === "true";
+ this.$widget.find('input[name="redirectBareDomain"]').prop("checked", redirectBareDomain);
+ this.$shareRootCheck.toggle(redirectBareDomain);
+ if (redirectBareDomain) {
+ await this.checkShareRoot();
+ }
- this.$widget.find('input[name="showLoginInShareTheme"]').prop("checked", options.showLoginInShareTheme === "true");
+ this.$widget.find('input[name="shareSubtree"]').prop("checked", options.shareSubtree === "true");
+ }
+
+ async checkShareRoot() {
+ const shareRootNotes = await searchService.searchNotes("#shareRoot", {
+ includeArchivedNotes: true,
+ ignoreHoistedNote: true
+ });
+
+ if (shareRootNotes.length > 0) {
+ this.$shareRootStatus
+ .removeClass('text-danger')
+ .addClass('text-success')
+ .text(t("share.share_root_found", {noteTitle: shareRootNotes[0].title}));
+ } else {
+ this.$shareRootStatus
+ .removeClass('text-success')
+ .addClass('text-danger')
+ .text(t("share.share_root_not_found"));
+ }
}
async save() {
const redirectBareDomain = this.$widget.find('input[name="redirectBareDomain"]').prop("checked");
await this.updateOption<"redirectBareDomain">("redirectBareDomain", redirectBareDomain.toString());
- const showLoginInShareTheme = this.$widget.find('input[name="showLoginInShareTheme"]').prop("checked");
- await this.updateOption<"showLoginInShareTheme">("showLoginInShareTheme", showLoginInShareTheme.toString());
+ const showLoginInShareTheme = this.$widget.find('input[name="shareSubtree"]').prop("checked");
+ await this.updateOption<"shareSubtree">("shareSubtree", showLoginInShareTheme.toString());
}
}
diff --git a/src/public/translations/en/translation.json b/src/public/translations/en/translation.json
index f2978237d..c0ee99e4b 100644
--- a/src/public/translations/en/translation.json
+++ b/src/public/translations/en/translation.json
@@ -1660,7 +1660,10 @@
"redirect_bare_domain": "Redirect bare domain to Share page",
"redirect_bare_domain_description": "When enabled, accessing the root URL will redirect to the Share page instead of Login",
"show_login_link": "Show Login link in Share theme",
- "show_login_link_description": "Add a login link to the Share page footer"
+ "show_login_link_description": "Add a login link to the Share page footer",
+ "check_share_root": "Check Share Root Status",
+ "share_root_found": "Share root found: {{noteTitle}}",
+ "share_root_not_found": "No note with #shareRoot label found. Set up a note with #shareRoot label first."
},
"time_selector": {
"invalid_input": "The entered time value is not a valid number."
diff --git a/src/services/auth.ts b/src/services/auth.ts
index 68c497b91..03f40e6e7 100644
--- a/src/services/auth.ts
+++ b/src/services/auth.ts
@@ -8,6 +8,7 @@ import passwordEncryptionService from "./encryption/password_encryption.js";
import config from "./config.js";
import passwordService from "./encryption/password.js";
import options from "./options.js";
+import attributes from "./attributes.js";
import type { NextFunction, Request, Response } from "express";
const noAuthentication = config.General && config.General.noAuthentication === true;
@@ -16,7 +17,15 @@ function checkAuth(req: Request, res: Response, next: NextFunction) {
if (!sqlInit.isDbInitialized()) {
res.redirect("setup");
} else if (!req.session.loggedIn && !isElectron && !noAuthentication) {
- const redirectToShare = options.getOption("redirectBareDomain") === "true";
+ const redirectToShare = options.getOptionBool("redirectBareDomain");
+ if (redirectToShare) {
+ // Check if any note has the #shareRoot label
+ const shareRootNotes = attributes.getNotesWithLabel("shareRoot");
+ if (shareRootNotes.length === 0) {
+ res.status(404).json({ message: "Share root not found. Please set up a note with #shareRoot label first." });
+ return;
+ }
+ }
res.redirect(redirectToShare ? "share" : "login");
} else {
next();