Runlight.Accounts (runlight v0.3.2)

Copy Markdown View Source

Accounts: who may sign in, their password hashes, two-factor, invites, and the signed cookie that keeps them signed in (the SDK's accounts/auth.ts). An app turns them on with Runlight.routes(rl, accounts: true).

The owner can do everything, and nobody else can remove them or change their role; they can hand ownership to an admin. An admin can do everything the owner can apart from that. A member changes sites, goals, links, and the rest, but not people, the mail service, the assistant's settings, or deleting a site. A viewer reads every site's stats and changes nothing.

A user is a JavaScript object: id, email, hash, role, createdAt, twoFactor, and recoveryLeft, and signedOut once the account has signed out.

Summary

Functions

Turns an invite into an account with the password its person chose. The link then stops working. It takes a turn, so it cannot cross a removal of whoever sent it, and the sender must still be someone who may invite.

Drops a set-up left half done, after too many wrong codes, so it must start again with the password.

Checks a six-digit code, or a recovery code, for an account with two-factor on. A code works once: one already used, or older, is refused, and a recovery code is crossed off. One check at a time per account here, and the database has the last word, since another process does not wait.

Turns two-factor on once a code from the new secret checks out, and returns ten recovery codes, shown once.

A long-lived mark for a browser that signed in to an account. A new password withdraws it.

Ends every session an account has, in every browser, as signing out does.

Removes the accounts and invitations kept to a site that was deleted. A site made later is often given the same id, from its domain, and they must not find their way into it.

The account a sign-in link is for. A link works once: using it withdraws it, and every link sent before it.

The account a code-step ticket names.

The signed-in user for a cookie value, or nil.

Makes an admin the owner, and the owner an admin.

Invites someone to join with a role, and returns the invite and the code for their link. Asking again replaces the earlier invite.

The invite a link's code belongs to, while it still works.

How long an invite link works.

Invites that still work, newest first. Expired ones are cleared on the way.

A ticket for a sign-in link sent by email, for fifteen minutes. A new password withdraws it.

The shortest password taken.

Accounts in an instance's database, signing with secret.

New recovery codes in place of the old ones.

A short-lived ticket naming an account whose password checked out and which still owes a code.

Removes an account. The owner cannot be removed.

The session cookie's name.

A cookie value naming the user and when it expires, signed with the server's secret and the user's password hash, so changing a password signs out every other browser.

Thirty days, renewed on every sign-in.

Makes an account, or sets a new password on an existing one. A new account is the owner when it is the first, and otherwise an admin unless a role is given, since a server has one owner.

Changes a role. The owner's never changes here, and nobody becomes the owner here: see hand_over/3.

The account for an email and password, or nil. Takes the same time either way. Only a few checks run at once; with too many waiting it raises an AccountError coded "busy".

Starts turning on two-factor: a new secret, kept aside until a code from it is confirmed.

Types

t()

@type t() :: %Runlight.Accounts{rl: term(), secret: term(), store: term()}

Functions

accept_invite(acc, code, password, now)

Turns an invite into an account with the password its person chose. The link then stops working. It takes a turn, so it cannot cross a removal of whoever sent it, and the sender must still be someone who may invite.

by_email(acc, email)

by_id(acc, id)

cancel_invite(acc, id)

cancel_two_factor_setup(acc, id)

Drops a set-up left half done, after too many wrong codes, so it must start again with the password.

check_second_factor(acc, id, code, now)

Checks a six-digit code, or a recovery code, for an account with two-factor on. A code works once: one already used, or older, is refused, and a recovery code is crossed off. One check at a time per account here, and the database has the last word, since another process does not wait.

confirm_two_factor(acc, id, code, now)

Turns two-factor on once a code from the new secret checks out, and returns ten recovery codes, shown once.

count(acc)

device_for(acc, user)

A long-lived mark for a browser that signed in to an account. A new password withdraws it.

disable_two_factor(acc, id)

end_sessions(acc, id)

Ends every session an account has, in every browser, as signing out does.

forget_site(acc, site)

Removes the accounts and invitations kept to a site that was deleted. A site made later is often given the same id, from its domain, and they must not find their way into it.

from_link(acc, value, now)

The account a sign-in link is for. A link works once: using it withdraws it, and every link sent before it.

from_pending(acc, value, now)

The account a code-step ticket names.

from_session(acc, value, now)

The signed-in user for a cookie value, or nil.

hand_over(acc, from, to)

Makes an admin the owner, and the owner an admin.

invite(acc, email, role, invited_by, now, site \\ nil)

Invites someone to join with a role, and returns the invite and the code for their link. Asking again replaces the earlier invite.

invite_by_code(acc, code, now)

The invite a link's code belongs to, while it still works.

invite_ms()

How long an invite link works.

invites(acc, now)

Invites that still work, newest first. Expired ones are cleared on the way.

list(acc)

min_password()

The shortest password taken.

new(rl, secret)

@spec new(Runlight.t(), String.t()) :: t()

Accounts in an instance's database, signing with secret.

new_recovery_codes(acc, id)

New recovery codes in place of the old ones.

pending_for(acc, user, now)

A short-lived ticket naming an account whose password checked out and which still owes a code.

remove(acc, id)

Removes an account. The owner cannot be removed.

session_cookie()

The session cookie's name.

session_for(acc, user, now)

A cookie value naming the user and when it expires, signed with the server's secret and the user's password hash, so changing a password signs out every other browser.

session_ms()

Thirty days, renewed on every sign-in.

set_password(acc, email, password, now, role \\ nil, site \\ nil)

Makes an account, or sets a new password on an existing one. A new account is the owner when it is the first, and otherwise an admin unless a role is given, since a server has one owner.

set_role(acc, id, role)

Changes a role. The owner's never changes here, and nobody becomes the owner here: see hand_over/3.

sign_in(acc, email, password)

The account for an email and password, or nil. Takes the same time either way. Only a few checks run at once; with too many waiting it raises an AccountError coded "busy".

start_two_factor(acc, id)

Starts turning on two-factor: a new secret, kept aside until a code from it is confirmed.

trusts_device(acc, value, user)

with_site(value, site)