# Accounts

```ts
import { accounts, hashPassword, verifyPassword } from '@athenox/talos'

export const users = accounts<Member>({
  store: app.store, table: 'users',
  expose: ['id', 'name', 'role'],          // what the session and responses hold (never the password)
  signUp: ['name'],                         // other columns a sign-up may set
  minPassword: 8,
  hash: hashPassword, verify: verifyPassword,   // scrypt; or bcrypt.hash / bcrypt.compare
  session: {                                 // any session store — here nuxt-auth-utils
    set: (event, user) => setUserSession(event, { user }),
    get: async event => (await getUserSession(event)).user,
    clear: clearUserSession,
  },
  as: 'user',                                // responses: { success, user }
  messages: { invalid: 'Wrong email or password' },
})
```

| handler | |
|---|---|
| `users.register` | `POST { email, password, ...signUp }` → signed in |
| `users.login` | `POST { email, password }` — JSON, or a plain HTML form with `redirect: { success, failure }` |
| `users.logout` | clears the session |
| `users.me` | the account, read again from the table |
| `users.change` | `POST { currentPassword, newPassword }` |
| `users.forgot` / `users.reset` | with `reset: { table, owner, send(account, token) }`: a one-time token, then a new password |

| helper | |
|---|---|
| `users.guard(check?)` | a route guard: the signed-in account read again from the table (a disabled one is refused), or 401; `check` refuses with 403 |
| `users.current(event)` | the account or `null` |

Other options: `email` / `password` (column names), `active` (a column that
disables an account), `onLogin: { last_login: () => new Date() }`, `read` (column
converters), `date` (how dates are stored). The same answer is given for an
unknown email, a wrong password and a disabled account.
