Skip to content

Staying Signed In

By default, the JavaScript client forgets the key when the page is reloaded, so your user types their passphrase (or signs in with Google, GitHub, ...) on every visit. To keep them signed in on a device they trust, ask for the device to be remembered when they sign in, and resume on the next visit.

Remember this device

Pass remember: true to getkey(), createkey() or a sign-in. Ask the user first, with a "Keep me signed in on this device" checkbox:

const db = await PrefsDB.getkey("todo-app", passphrase, { email, remember: keepSignedIn });

// The same with a provider's sign-in, or the sign-in buttons:
//   await PrefsDB.getkeyWithIdToken(idToken, { remember: true })
//   PrefsDB.signIn({ google: { clientId }, remember: true, onSignIn: start }).mount(el)
# The answer has "deviceGrant": { "token": "...", "id": 7, "expires": "..." }
curl -s -c cookies.txt -G https://prefsdb.com/api/v1/getkey/ \
  -d name=todo-app -d seed="$SEED" -d remember=1

The browser keeps a device grant: a secret, separate from the passphrase, that lets this browser get the key back for 30 days. remember: { days: 90 } asks for longer (90 days at most). remember: { device: "Kitchen tablet" } gives the device a name for the list of devices.

Resume after a reload

On the next visit, call PrefsDB.resume() with the same name you passed to getkey() (a sign-in's name, or "default" if you didn't give one). It resolves to the same ready-to-use instance getkey() would, or to null when there's nothing to resume. Show your sign-in page then:

const db = await PrefsDB.resume("todo-app") ?? await showSignIn();
  • It returns null when this browser was never remembered, the grant ran out, or the user signed out or removed the device.
  • Offline, it still resolves to the key (db.resumedOffline is true). Reads come from the browser's offline copies, and changes are saved and sent when the connection is back.
  • PrefsDB.canResume("todo-app") says straight away, without a request, whether there's a grant to try. Use it to show "Welcome back" instead of the sign-in form.
  • Client-side encryption keys are never remembered. Pass encryption to resume() as you would to getkey().

Seeing and removing devices

db.devices() lists the devices the key is remembered on: each one's name (the browser and system, such as "Firefox on Windows", unless you named it), when it was remembered and last used, and current for this browser. db.revokeDevice(id) signs one out, and db.revokeAllDevices() signs out all of them:

const { devices } = await db.devices();
for (const d of devices) console.log(d.label, d.lastUsed, d.current ? "(this device)" : "");
await db.revokeDevice(devices[1].id);
curl -s -b cookies.txt -H "X-Authorization: Token $KEY" https://prefsdb.com/api/v1/devices/
curl -s -b cookies.txt -H "X-Authorization: Token $KEY" https://prefsdb.com/api/v1/devices/ \
  -d action=revoke -d id=7

A removed device can't resume any more, from that moment. The session it already has runs out within a minute. Your users can do the same from the key's own page (its review link), under Devices.

Signing out

db.logout() also forgets this device: the grant is deleted from the browser and revoked on the server, so resume() returns null here afterwards. PrefsDB.forgetResume("todo-app") does the same without an instance, for a "Not you?" link. With the sign-in buttons, signin.signOut() calls logout() for you.

What it means for security

A remembered device can use the key without the passphrase or a sign-in. The trade-off:

  • Anyone who can use that browser can open the data while the grant lasts. On a shared or public computer, don't offer "Keep me signed in", or leave the box unticked by default.
  • Anything that can read the page's storage can take the grant: a browser extension, or a script injected into your site. Taken elsewhere, it works there too until it expires or is removed. Keep your site free of scripts you don't trust.
  • Removing it works at once. If a device is lost, or the user doesn't recognise one in the list, remove it (or all of them) and that device is signed out.

The passphrase itself is never stored, so a remembered device can't reveal it.