Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internal url handler for referencing other entries #5369

Open
networkException opened this issue Sep 1, 2020 · 24 comments
Open

Internal url handler for referencing other entries #5369

networkException opened this issue Sep 1, 2020 · 24 comments

Comments

@networkException
Copy link

networkException commented Sep 1, 2020

Summary

Add a url sceme for referencing other entries.
This request would make use future html support with the anchor tag.

Examples

For this example I'm using a simple database structure:

The entry "github" is nested inside the group "accounts", which itself is nested inside "root".
In the advanced edit widget there is an additional attribute called "backup codes".

<!-- The path specified specifies an entries location -->
<a href="keepassxc://root/accounts/github/">Opens the main edit widget of "github"</a>

<!-- ... or opens a group. -->
<a href="keepassxc://root/accounts/">Show the "accounts" group</a>

<!-- If the path "ends" and there are no other parameters, 
its possible to just highlight the target group or entry in its parent "scope" -->
<a href="keepassxc://root/accounts/github/?outer=true">Opens the entry's parent group and focuses "github"</a>

<!-- Continue the path to show a specific widget in an entry -->
<a href="keepassxc://root/accounts/github/main/">Opens the main edit widget of "github"</a>
<a href="keepassxc://root/accounts/github/advanced/">Opens the advanced edit widget of "github"</a>
<a href="keepassxc://root/accounts/github/history/">Opens the history edit widget of "github"</a>

<!-- As the advanced area has two subwidgets which have named subentries, 
they can continue the path as well -->
<a href="keepassxc://root/accounts/github/attributes/">Opens the advanced edit widget of "github"</a>
<a href="keepassxc://root/accounts/github/attachments/">Opens the advanced edit widget of "github"</a>
<a href="keepassxc://root/accounts/github/attributes/backup%20codes/">
    Opens the advanced edit widget of "github" and selects the "backup codes" attribute
</a>

<!-- If the path leads to some sort of text area, 
there are parameters for going to some specific line and column -->
<a href="keepassxc://root/accounts/github/main/note/?line=2&column=4">
    Some line and column in the notes of "github"
</a>
<a href="keepassxc://root/accounts/github/attributes/backup%20codes/?line=2&column=4">
    Some line and column in the "backup codes" attribute of "github"
</a>

I'm open for more suggestments / adjustments to the sceme

Context

This feature could allow users to further organize their database.
For example someone might have one entry for payments, but they for example still want a reference
for all payments made on github in their github account entry.

@OLLI-S
Copy link

OLLI-S commented Sep 1, 2020

Good suggestion, I suggest an enhancement:
Instead of the scheme keepass: the scheme keepassxc: should be used.

So this will be (taking the first example above):

<!-- The path specified specifies an entries location -->
<a href="keepassxc://root/accounts/github/">Opens the main edit widget of "github"</a>

@networkException
Copy link
Author

Yea ok that seems reasonable, I will change it in the examples

@droidmonkey
Copy link
Member

droidmonkey commented Sep 2, 2020

We should make it application agnostic in case others want to implement it. Recommend something like entryref://[uuid | path]/[attribute] and groupref://[uuid | path]. This could become a replacement to the attribute reference schema as well.

@networkException
Copy link
Author

networkException commented Sep 2, 2020

If others want to implement it I would say that the sceme should just be keepass. However specifying the "type" of entity (group, entry, etc.) in the url is something I would add as well.

I was thinking of using the tld as the type of identifier used and the sld as the type of entity referenced.

<a href="keepass://group.path/root/accounts/">Opens the "accounts" group by path</a>
<a href="keepass://entry.uuid/21ea1457b4ec418496d1811b0a9b67cb/">Opens the "github" entry by uuid</a>

As soon as there is agreement on this I will rewrite the main comment and work out a full specification.

@droidmonkey
Copy link
Member

Using the tld is clever, go ahead and write up the final proposal.

@networkException
Copy link
Author

Alright here it is keepass-url-spec.md. I'm happy to take any feedback because this is really the first time I've written something comparable

@droidmonkey
Copy link
Member

droidmonkey commented Sep 22, 2020

Hmmmmm, couple points, then I will show some changes through examples.

  1. The root group is never spelled out in our path conventions, we always start simply with /
  2. An action should be in the query string, this allows the crafter/reader of the URL to flow from left to right:
    keepass://[attribute]@[object-type].[ref-type]/[ref]?[action(s)]#[anchor]
<a href="keepass://group.path/accounts/">Show the "accounts" group</a>
<a href="keepass://entry.path/accounts/github/">Focuses on the entry in it's parent group</a>

<a href="keepass://entry.path/accounts/github?edit">Opens the main edit widget of "github"</a>
<a href="keepass://entry.uuid/21ea1457b4ec418496d1811b0a9b67cb?edit">Opens the main edit widget of "github"</a>

<a href="keepass://entry.path/accounts/github?edit#advanced">Opens the advanced edit widget of "github"</a>
<a href="keepass://entry.path/accounts/github?edit#history">Opens the history edit widget of "github"</a>

<a href="keepass://entry.path/accounts/github?attribute=backup%20codes">
Opens the advanced edit widget of "github" and selects the "backup codes" attribute</a>

<a href="keepass://backup%[email protected]/accounts/github">
Opens the advanced edit widget of "github" and selects the "backup codes" attribute</a>

<a href="keepass://entry.path/accounts/github/?attribute=Notes&line=2">Select line 2 of "github" notes</a>

<a href="keepass://entry.uuid/21ea1457b4ec418496d1811b0a9b67cb?customdata=_LAST_MODIFIED">
Hightlights the "_LAST_MODIFIED" key value pair in the plugin data widget</a>

<a href="keepass://db.uuid/34eb1447b7ec218446d1451b0c9b49a1?entry=21ea1457b4ec418496d1811b0a9b67cb&attribute=Password">
Go to open database with uuid 34eb1447b7ec218446d1451b0c9b49a1 open the entry with 
uuid 21ea1457b4ec418496d1811b0a9b67cb and highlight it's password</a>

I would love this syntax to replace/augment the {REF:...} syntax. For example, to fill the password from an entry: keepass://[email protected]/21ea1457b4ec418496d1811b0a9b67cb

I am in favor of supporting a scheme like dbref:// in addition to keepass://.

@networkException
Copy link
Author

networkException commented Sep 22, 2020

I actually didn't know that you can't name an additional attribute "Title", "Password" and so on, so a distinguishment between integrated and additional as the attribute type isn't really nessesarry

  1. I wasn't really sure about root, for me it just looked like a group that is contained in the actual root of the database, but I might be wrong. (here a picture of the entry of the example database I used)
    grafik
  2. I quite like that change because it indeed makes the url more readable.

I opted for choosing the third level domain to specify the attributeType because a user might have an attachment called "Notes", which then would make the attribute "Notes" inaccessible. Same goes with custom / plugin data. I like the keepass://backup%[email protected]/accounts/github syntax as well but it doesn't specify that type.
Should the attributeType just be left out and risk it being ambigous? Should some other segment be used? And should this just replace the entries history?

Another thing I am not completely sure about is
keepass://db.uuid/34eb1447b7ec218446d1451b0c9b49a1?entry=21ea1457b4ec418496d1811b0a9b67cb#Password.
Having db as an entity type surely isn't a bad idea, but this exact example brings makes both the reference type and the attribute type ambigous. I am not sure if this should be possible as an entry in root with the name "21ea1457b4ec418496d1811b0a9b67cb" might not be possible for example. Same goes with an attachment named "Password". Also I was wondering if db.path/home/user/desktop/keepass.kdbx should be allowed.

Suppporting dbref:// seems reasonable as well.

@droidmonkey
Copy link
Member

Attributes are all the same. There are a few reserved names. You can see them in EntryAttributes.h

@networkException
Copy link
Author

alright I see

@droidmonkey
Copy link
Member

droidmonkey commented Sep 23, 2020

I realize you are comparing attachments and attributes. Those are two completely different aspects of an entry. To reference an attachment by name I would craft this url:

<a href="keepass://entry.path/accounts/github/?attachment=notes.txt">Select attachment "notes.txt" of github entry</a>

I modified my examples above to actually use the query string as intended.

@networkException
Copy link
Author

networkException commented Sep 23, 2020

So what I'm still wondering about is the syntax for history items. In my scheme I used the part before the @ (which is now used for attributes) to reference them by timestamp. Should this not be implemented at all or should I use some other url segment for it?

Additionally, the db entity type still causes some headache for me, as this url doesn't specify the referenceType of the entry.
keepass://db.uuid/34eb1447b7ec218446d1451b0c9b49a1?entry=21ea1457b4ec418496d1811b0a9b67cb&attribute=Password.

The following would be my approach

<a href="keepass://[email protected]/34eb1447b7ec218446d1451b0c9b49a1/?entry.uuid=21ea1457b4ec418496d1811b0a9b67cb">
Go to open database with uuid 34eb1447b7ec218446d1451b0c9b49a1 open the entry with 
uuid 21ea1457b4ec418496d1811b0a9b67cb and highlight it's password
</a>
<a href="keepass://[email protected]/34eb1447b7ec218446d1451b0c9b49a1/?entry.path=/accounts/github/">
Go to open database with uuid 34eb1447b7ec218446d1451b0c9b49a1 open the entry with the path /accounts/github/ and highlight it's password
</a>
<a href="dbref://db.uuid/34eb1447b7ec218446d1451b0c9b49a1/?entry.path=/accounts/github/&attribute=Password">
Go to open database with uuid 34eb1447b7ec218446d1451b0c9b49a1 open the entry with the path /accounts/github/ and highlight it's password
</a>
<a href="dbref://db.uuid/34eb1447b7ec218446d1451b0c9b49a1/?entry.path=/accounts/github/&attachment=notes.txt">
Go to open database with uuid 34eb1447b7ec218446d1451b0c9b49a1 open the entry with the path /accounts/github/ and highlight a file named "Notes.txt"
</a>

@droidmonkey
Copy link
Member

droidmonkey commented Oct 1, 2020

History of entries should be referenced through the query string: keepass://entry.path/accounts/github?edit&history=[timestamp|index] this will open the entry edit view of the particular history item. You can reference history by explicit timestamp or index (0 = current, 1 = previous, 2 = ...)

I like the entry.uuid and entry.path query selectors for the db entity, keeps it consistant.

@networkException
Copy link
Author

alright that sounds good. I will update my specification as soon as possible.

@networkException
Copy link
Author

After a lot of thinking I came up with a overhaul of the specification. I think it all comes togeher quite nicely now. However I changed some syntax for edge cases. Notably, that widget referencing doesn't require github/?edit#widget anymore, I think a special syntax using the fragment (or hash) is enough and doesn't need a key in the query string on top (github#widget).

https://gist.github.com/networkException/b1ccad6f338fe086db6f38031fb431a8

Please tell me if I forgot to add something, I haven't done everything on one go.

@droidmonkey
Copy link
Member

The action of edit is necessary to distinguish merely selecting the entry in the view and opening it for editing. Being explicit resolves a lot of ambiguous use cases.

We would also want to include actions for clipboard and autotype as well.

@networkException
Copy link
Author

So keepass://entry.path/accounts/github#main would show a read only version of the entry while keepass://entry.path/accounts/github?edit#main would open it as editable?

@droidmonkey
Copy link
Member

droidmonkey commented Oct 16, 2020

Not a read only version, just select it in the entry view. The edit action opens the entry edit widget and the anchor points to the tab to show (if included)

@networkException
Copy link
Author

Ok so the syntax you proposed looked like this:

keepass://entry.path/accounts/github Selects the entry in its parent group
keepass://entry.path/accounts/github?edit Opens the entry in the main edit widget
keepass://entry.path/accounts/github?edit#widget Opens a specified widget of the entry

Now what I suggested:

keepass://entry.path/accounts/github Selects the entry in its parent group
keepass://entry.path/accounts/github# Opens the entry in the main edit widget
keepass://entry.path/accounts/github#widget Opens a specified widget of the entry

As it gives use to the fragment without breaking consistency and creating an unnessearry edge case. The fragment is not related to the query string at it doesn't make sense to store a value of a key in the query string in the fragment.

A completely different idea would be to drop the usage of the fragment and just use the query string:

keepass://entry.path/accounts/github Selects the entry in its parent group
keepass://entry.path/accounts/github?edit Opens the entry in the main edit widget
keepass://entry.path/accounts/github?edit=widget Opens a specified widget of the entry

The more I think about it I actually like it more. It still provides a descriptive key edit but doesn't create an edge case syntax wise by using the fragment.
It would also mean that I would probably drop the showInParent as its kinda useless.

@droidmonkey
Copy link
Member

droidmonkey commented Oct 20, 2020

I like that better too, the dropping of fragments

@networkException
Copy link
Author

Alright that should be changed now. I'm quite happy with the consistency of the new edit syntax.

@tunbridgep
Copy link

tunbridgep commented Sep 4, 2021

I really just wish we could use the simple, already implemented references for this

<a href="{REF:I:1263781623861283618231}">See This Entry for details</a>

with some basic html attributes to do stuff, rather than weird, long url schemas:

Some examples:

  • <a action="show" href="{REF:I:1263781623861283618231}">See This Entry for details</a>, for instance, to jump to the parent group and highlight the entry
  • <a action="edit" display="tooltip" href="{REF:I:1263781623861283618231}">See This Entry for details</a>, for instance, to jump to the entry itself, with a tooltip showing basic information about the entry on hover

Would also love to display information from other entries (or the same entry) simply by referencing it.

Password must not be the same as {REF:P@I:1263781623861283618231}!

Which would be displayed as

Password must not be the same as foo123!

As well as special reference syntax for our own attributes

The password for this entry is {REF:P@I:self}!

We should use UUIDs as they are more stable than paths if we move entries around, and it seems much simpler/easier. Attributes also allow more features to be added and chained together, which is generally horrible with GET parameters.

I guess your method is technically more HTML compliant, though.

@Anubis-105

This comment was marked as off-topic.

@networkException

This comment was marked as off-topic.

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

No branches or pull requests

6 participants