BrT

Musings about technology and other neat stuff

BrT random header image

How to define a new wallet item in 1Password

December 17th, 2007 · 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: · · · ·