BrT

Musings about technology and other neat stuff

BrT random header image

How to define a new wallet item in 1Password

December 17th, 2007 · 11 Comments

Update 1: I have modified the perl script to include Damon’s modification (see the comments) to make it work properly with the UTF-encoded Localizable.strings file used in recent 1Password versions.

Update 2: Somewhere around version 2.8.3 of 1Password there were some changes that make the original script not work anymore. I have updated the instructions and the script to make it work with the new versions. If you are still using an old version of 1Password (and why would you?) you can find the original script here

Update 3: Recent versions of 1Password include a built-in Wallet item type called “Unix server” which pretty much includes everything the one I invented had, so I have stopped using (and maintaining) this hack.

I have been using 1Password lately to manage both online and other passwords, and I quite like it. It integrates nicely with most browsers, and its auto-save and auto-fill features are very handy. I also like its “wallet items” feature, which allow you to save other pieces of information, such as credit card numbers, email account information, etc. Unfortunately the selection of wallet item types that is available is limited, and while it seems to grow with every new release, it’s still missing some items that for me are indispensable.

Here’s how I added a “Login Information” wallet item to store arbitrary username/passwords for different services. Fortunately, 1Password seems to be nicely modularized, and wallet types are defined in separate files for the most part (the only exception being the localized strings). I based my work off the pre-defined “MySQL Database” wallet item, which seemed the most similar to what I needed.

So here are the steps I followed:

(note: I have automated these steps in a Perl script – use with care once you have done the steps manually)

  1. Quit 1Password. Make a copy of /Applications/1Password.app and of your data (/Users/zamboni/Library/Keychains/1Password.keychain) in case anything goes wrong.
  2. The rest of these steps take place inside /Applications/1Password.app/. You can either work from the terminal or open it from the Finder (right click on the app icon and choose “Show package contents”).
  3. Copy Contents/Resources/datatypes/2902-mysql.js to Contents/Resources/datatypes/2904-login.js, and edit it to look like this:
    {
      "class":"wallet.computer.LoginInformation",
      "contents":[
        {
          "set":"",
          "disclosed":"yes",
          "fields":[
            { "name":"hostname", "type":"string" },
            { "name":"service", "type":"string" },
            { "name":"username", "type":"string" },
            { "name":"password", "type":"concealed" }
          ]
        }
      ]
    }
    

    This defines the fields that will be used by the new wallet type. I think the numbering is arbitrary, but 2904 is the next unused number after “2903-router.js”, which is the last one in the “Computer and Network Information” section of the “Add Wallet Item” dialog in 1Password.

  4. Copy Contents/Resources/English.lproj/DetailView/standard/wallet.computer.MySQLConnection.html to Contents/Resources/English.lproj/DetailView/standard/wallet.computer.LoginInformation.html (the name has to match the “class” defined in the .js file above). This defines how the wallet item will be displayed when viewed in the list. I modified it to look like this (note: recent versions of 1Password changed the .html field to .ag_html, I have reflected this change below and in the downloadable script):
    <h1><img class="titleIcon" src="[template.baseURL]/WalletIcon.png" width="32" height="32" alt="Secure Note" />[object.title.ag_html]<input type="button" class="editTop" value="Edit" onclick="javascript:controller.editObject('[object.uuid]')" /></h1>
    
    <div class="contentPadding">
    
    <p class="notes"><span class="label">Notes:</span>[object.notesHTML]</p>
    
    <p>
    
    <table class="dynamicFields" cellpadding="0" cellspacing="0">
      <tr>
        <th><span class="name">Hostname:</span></td>
        <td><span class="value">[object.secureContents.hostname.ag_html]</span></td>
      </tr>
      <tr>
        <th><span class="name">Service:</span></td>
        <td><span class="value">[object.secureContents.service.ag_html]</span></td>
      </tr>
      <tr>
        <th><span class="name">Username:</span></td>
        <td><span class="value"><a class="copy" href='javascript:controller.copyToClipboardFieldOfObject("secureContents.username", "[object.uuid]")'>[object.secureContents.username.ag_html]<span class="copyButton">Copy</span></a></span></td>
      </tr>
      <tr>
        <th><span class="name">Password:</span></td>
        <td><span class="value"><a class="copy" href='javascript:controller.copyToClipboardFieldOfObject("secureContents.password", "[object.uuid]")'>[object.secureContents.password.concealed.ag_html] <span class="copyButton">Copy</span></a></span></td>
      </tr>
    </table></p>
    </p>
    <p><span class="label">Created: [object.createdAt] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Last modified on: [object.updatedAt]</span></p>
    </div>
    
  5. Add the following lines to Contents/Resources/English.lproj/Localizable.strings:
    "wallet.computer.LoginInformation" = "Login Information";
    "wallet.computer.LoginInformation.desc" = "Generic login information.";
    "wallet.computer.LoginInformation.hostname" = "Hostname";
    "wallet.computer.LoginInformation.service" = "Service";
    "wallet.computer.LoginInformation.username" = "Username";
    "wallet.computer.LoginInformation.password" = "Password";
    

    This defines the strings that will be used in the entry and display forms for the item.

That’s it. Restart 1Password, and you should see the new wallet item type in the list of available types (in this case, under “Computer and Network Information”).

Disclaimers:

  1. In recent versions 1Password introduced the “Unix server” wallet item, which contains the same information as the one I defined, plus some additional items. You may want to use that instead of modifying the application, but the method described above still works if you want to use it.
  2. This should be clear, but this is a completely unsupported procedure, which I discovered by exploring inside the application. It could stop working at any time, it probably doesn’t work if you are using a localized non-English version (maybe you need to modify different files), and it could destroy your data, uproot your plants and kill your kittens. Don’t blame me.
  3. I used this method first with 1Password 2.5.7, and have tested it up to 2.8.3-beta6. Older/newer versions may or may not work.
  4. Be careful – make copies of your data and applications before modifying things like described here.

Tags: · · · ·

11 responses so far ↓

  • 1  David A Teare // Dec 18, 2007 at 8:28 pm

    That is some good hacking! ;-)

    I actually was planning on adding LoginInformation to the next release, so maybe I will just copy your files! :)

    If you have other templates, just send them to me and most likely I will add them. The idea is to have about 50-100 templates that will help new users understand the possibilities of what can go into the Wallet. After that we will add the ability to customize existing templates and add additional ones.

    Cheers!
    –Dave Teare
    Co-author of 1Password

  • 2  Hitchhiker // Dec 19, 2007 at 1:21 am

    Hi David, thanks for the comment! If I define any new templates I’ll certainly send them to you :-)

  • 3  Carsten // Feb 14, 2008 at 11:38 am

    Hi
    First i want to thank you for that great tutorial
    But i’ve got a question
    How can i use the perl script?

    best regards Carsten

  • 4  Hitchhiker // Feb 14, 2008 at 3:40 pm

    Carsten: you have to save the script to a file, and from the Terminal run it with this command: “perl install_1password_new_wallet_items.pl” (without the quotes).

  • 5  Carsten // Feb 14, 2008 at 3:45 pm

    great, thank you

  • 6 DCortesi . blog » Unicode Grep // Jul 17, 2008 at 3:19 am

    [...] got caught by a bit of a bug today when I was trying to add a custom wallet item in 1Password. I was in the process of copying one of their templates after realizing they were just simple json, [...]

  • 7  Ingmar // Jul 29, 2008 at 3:08 pm

    Tank you for this great script. But it does not work anymore. The File Localizable.strings is not formated right. I think this has to do with the UTF-16 UTF-8 problem mentioned above. Can you perhaps fix this bug?

    Thanks forward

  • 8  Hitchhiker // Jul 29, 2008 at 11:10 pm

    Ingmar: I have noticed this problem myself, but I have not had time to fix it properly. What I have been doing for now is:
    - Run the script
    - Open the file Localizable.strings with TextEdit
    - Remove the strange characters left by the script from the end of the file, and then copy/paste manually the lines from step 5.

    I will try to fix it ASAP, as it has also been bugging me :-)

  • 9  Damon // Aug 15, 2008 at 9:10 am

    Diego – Many thanks for posting this script. It came in handy after I updated and didn’t back up my modifications. ;)

    I ran into the UTF-16 issue and was able to replace line 98 with the following statement, which seemed to work (and will hopefully post properly):

    open F, “>>:raw:perlio:encoding(utf16be)”, $file or die “Error opening $file for appendn”;

  • 10  Hitchhiker // Aug 15, 2008 at 10:35 pm

    Damon: thank you for the line! It works perfectly, I have modified the script to include it.

  • 11 Updated script for defining a new wallet item in 1Password // Sep 8, 2008 at 2:52 pm

    [...] you have been using my method for defining new wallet items in 1Password, you may have noticed that in recent versions the display of those new items has been broken. I [...]