Skip to content

feat: read-only shareable note links - #136

Open
antonbezr wants to merge 1 commit into
brufdev:mainfrom
antonbezr:feature/read-only-shareable-note-links
Open

feat: read-only shareable note links#136
antonbezr wants to merge 1 commit into
brufdev:mainfrom
antonbezr:feature/read-only-shareable-note-links

Conversation

@antonbezr

@antonbezr antonbezr commented Aug 5, 2026

Copy link
Copy Markdown

Hello!

First of all big fan of the app, been really enjoying it.

I was looking through the following issues/discussions for adding read-only note publishing:
#46
#47

I built this feature for myself anyway but I was wondering if it would be feasible to get it review and pushed upstream. If you have the bandwidth please take a look and lmk. Happy to iterate on this as well for it to align with the overall app design if any current behavior/patterns are not desired.


The change is architectured as follows:

Database

One new table: vault_node_shares

  • id
  • vault_node_id - FK to vault_nodes, unique (so a note can have at most one active share), cascadeOnDelete() (deleting the note automatically revokes its share)
  • token - random 48-char string, unguessable, used as the public URL identifier instead of the numeric ID
  • timestamps

Relationships

  • VaultNode::share()hasOne(VaultNodeShare)
  • VaultNodeShare::node()belongsTo(VaultNode)

Authorization

VaultNodePolicy::share() - same rule as the existing delete() ability: the vault owner or an accepted collaborator. Nothing else can create or revoke a link.

Routes

Authenticated - (inside the existing auth middleware group, under vaults/{vault}/nodes/{node}):

  • POST .../share - create (or return existing) link
  • DELETE .../share - revoke

Public - a new route group that sits outside both auth and guest middleware (works whether you're logged in or not), keyed by the token via Laravel's {share:token} route-model binding:

  • GET /share/{token} - renders the read-only note page
  • GET /share/{token}/files?path=... - serves images embedded in that note
    • The app already has /files/{vault}?path=... for serving attachments, but that endpoint checks "can this user view the whole vault
    • /share/{token}/files instead re-parses the note's current markdown content on every request, extracts just the image paths actually referenced in it, and only serves those (unsure if this is preferred from a design perspective but lmk thoughts)

Screenshot 2026-08-05 at 1 55 36 PM Screenshot 2026-08-05 at 1 55 45 PM Screenshot 2026-08-05 at 1 56 04 PM Screenshot 2026-08-05 at 1 56 47 PM Screenshot 2026-08-05 at 1 56 51 PM Screenshot 2026-08-05 at 1 57 32 PM Screenshot 2026-08-05 at 1 59 59 PM Screenshot 2026-08-05 at 2 32 43 PM

What the button looks like after hitting copy to clipboard (goes away after 1 second):
Screenshot 2026-08-05 at 2 33 06 PM

Also here is what the settings button shows, I didn't use the entire header for the read-only mode because it seemed cleaner to not have it when it would contain very limited controls. Also I didn't use the person icon and instead used the gear since technically in read only mode the user is a guest. Let me know any thoughts around this happy to change it:
image

@brufdev

brufdev commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Hi @antonbezr! I think this is a good feature to add, so thank you for your work!

I did a quick review and liked the UI/UX and the overall code, but I will need to do a deeper review. I don't have much free time these days, but I will do it as soon as possible.

One thing I noticed and didn't like was that the public page loads the Tiptap editor to display the HTML. Wouldn't it be better to use the markedService to convert the content to HTML and just display that markup instead?

The main branch contains the code for the latest release, while the dev branch has the code for the next release. You'll need to point this PR to the dev branch instead of main. I'm already working on the next release, so you'll need to rebase and resolve any conflicts. However, wait for my full review, so you'll only need to do it once.

@antonbezr

Copy link
Copy Markdown
Author

Thanks for taking a quick look!

I read about building on top of dev branch but somehow I forgot, I will follow up on that in next commit.


Regarding tiptap vs. marked. From my understanding tiptap still does a bunch of styling overlay not limited to editing which would still be relevant to read-only mode.

For example like the code syntax highlighting (CustomCodeBlockLowlight) and also images (CustomImage + renderer.image is not overwritten in marked.ts).

Seemed a little more straightforward to use tiptap since it's already setup for read-only mode through isEditMode.

Happy to change it though, I think marked service would need to be able to handle some of that rendering? I could take a closer look and make that change first instead if it seems reasonable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants