# Invite users

> Bring your colleagues into nexxus. This guide covers every way an account comes about, what the invited person sees, the user list and detail page, removing access, and how an account links to a person and a company.

In nexxus you never hand anyone a password. You invite the person: nexxus creates the account with its roles, sends a link by email, and the person chooses their own password. Until they do, the account exists but nobody can sign in with it.

Take Brandt & Söhne, a 60-person installation company. On the day they start with nexxus, their admin pastes 24 email addresses from Outlook into the setup wizard. Everyone gets the default role „Mitarbeiter:in“ (employee). The two team leads get their own role in a second step, and the bookkeeper is invited on her own with the role „Verwaltung“ (administration). By lunchtime everyone has chosen a password and signed in.

## Ways to an account

There are five ways an account comes into existence. Pick the one that fits the person.

| Way | Who starts it | Password | Use it for |
|---|---|---|---|
| **Invitation** (one person) | An admin, on the user list | The person sets it via the email link | The normal case |
| **Invitation** (many at once) | An admin, in the setup wizard | Each person sets it via the email link | Onboarding a whole team |
| **Account created directly** | An admin, on the user list | nexxus generates a temporary password that must be changed at the first sign-in | People without a mailbox, or a password handed over in person |
| **First sign-in with Microsoft** | The person | None, they sign in with Microsoft | Companies on Microsoft 365, see [Sign-in and OAuth](/setup/sign-in/) |
| **First administrator** | Whoever sets up a new installation | Chosen on the setup page | Once per installation, see [First run](/setup/first-run/) |

An invitation goes through four stages:

<Flow
  steps={[
    { icon: 'user-plus', title: 'You invite', text: 'Name, email, company and roles. The account is created and locked.' },
    { icon: 'mail', title: 'nexxus sends a link', text: 'Valid for 7 days, usable once.', tone: 'cyan' },
    { icon: 'key-round', title: 'The person sets a password', text: 'At least 12 characters, checked against known data breaches.', tone: 'lavender' },
    { icon: 'log-in', title: 'They sign in', text: 'With the roles you gave them, from the first click.' },
  ]}
  caption="The account and its roles exist from the moment you invite. Only signing in waits for the person."
/>

## Before you start

- You hold the system role **ADMIN**. Only administrators may invite people, create accounts and open the user list.
- **Mail sending works.** Invitations go out through the mail server set up in the step <Ui>Email</Ui> of the setup wizard. Until that step is confirmed, invitations wait in the queue.
- **There is at least one branch of a company.** Every person belongs to a company through one of its branches, and the invitation asks for it. The first own company and its branch are created when you enter <Ui>Organization name</Ui> in the setup.
- **Your roles exist.** The invitation assigns access roles. If you have not set them up yet, read [Roles and rights](/setup/roles/) first, or rely on the default role from the setup.

## Invite one person

<Screenshot src={shot_users_list} url="/user" alt={"The user list with one pending invitation and the overview panel"} caption={"Pending invitations carry their own chip until the person sets a password."} />

<Steps>

1. Open <MenuPath to="Administration > Users & access > Users" />. The page <Ui>Users</Ui> lists every account of your workspace.

2. Click <Ui>Invite person</Ui> at the bottom of the page. The dialog explains what happens: <Ui>Sends an invitation link. The account is locked until the invitation is accepted.</Ui>

   <Screenshot src={shot_users_invite_dialog} url="/user" alt={"The invitation dialog with two roles"} caption={"Roles are assigned with the invitation, tenant-wide by default."} />

3. Fill in <Ui>Username *</Ui> and <Ui>Email address *</Ui>, and optionally <Ui>First name</Ui> and <Ui>Last name</Ui>. The username is what the person types to sign in. It must be unique across the whole installation, and so must the email address.

4. Choose the branch under <Ui>Company / branch *</Ui>. Branches appear as "Name (City)". A branch of an own company makes the person an employee; a branch of a customer makes them a contact at that customer (see [How an account links to a person and a company](#how-an-account-links-to-a-person-and-a-company)).

5. Under <Ui>Permissions</Ui>, pick an access role and its scope, then click <Ui>Add</Ui>. The scope is <Ui>Tenant-wide</Ui> by default, which is what you want in most cases. You can add several roles. Each row has a control to remove it again.

   If you add no role at all, nexxus warns you that the person can sign in but will see nothing. If you send the invitation anyway, the person gets the default role of your workspace (set in the setup step <Ui>Roles</Ui>).

6. Click <Ui>Send invitation</Ui>. A message <Ui>Invitation sent to</Ui> with the address confirms it, and the person's card in the list carries the chip <Ui>Invitation pending</Ui>.

</Steps>

## Invite many people at once

The setup wizard has a step that takes a whole list of addresses. It is the fastest way to bring in a team, and you can come back to it at any time.

<Steps>

1. Open <MenuPath to="Administration > Operations > Setup" /> and choose the step <Ui>Invite people</Ui> (during the first setup it is the last step of the wizard).

   <Screenshot src={shot_users_bulk_invite} url="/onboarding?step=invite" alt={"Four addresses checked before the invitations go out: new, already has an account, duplicate"} caption={"nexxus checks every address before anything is sent."} />

2. Paste the addresses into <Ui>Email addresses, one per line or separated by commas</Ui>. Pasting from Outlook or a spreadsheet works. nexxus guesses names from the addresses: `tom.keller@example.com` becomes Tom Keller.

3. Click <Ui>Check addresses</Ui>. nexxus shows a table with the columns <Ui>Email</Ui>, <Ui>Name</Ui>, <Ui>Role</Ui> and <Ui>Status</Ui>. The status tells you what will happen to each address:

   | Status | Meaning |
   |---|---|
   | <Ui>New</Ui> | Will be invited |
   | <Ui>Invited</Ui> | Has already been invited |
   | <Ui>Already has an account</Ui> | An account with this address exists, nothing is sent |
   | <Ui>Address incomplete</Ui> | Not a usable email address |
   | <Ui>Duplicate</Ui> | Appears twice in your list |

4. For each new address, choose a role, or <Ui>No access role</Ui>. The box <Ui>What people receive</Ui> on the right reminds you: an invitation by email with a link to set their password, and the role you chose, otherwise the default role.

5. Click the send button, for example <Ui>Send 22 invitations</Ui>.

</Steps>

The username of a person invited this way is their email address in lower case. **Bulk invitations do not assign a company.** Open each person afterwards and set <Ui>Company / branch</Ui> on the tab <Ui>Master data</Ui>. You can invite at most 200 addresses at once.

## What the invited person sees

The invitation arrives as an email from nexxus. Mails from the server are written in German, whatever language the person uses in the app. The subject reads „Ihr Zugang zu“ (your access to) followed by the product name, the email names the username, and the button **„Zugang aktivieren“** (activate access) opens the sign-in page. The small print says the link is valid for 7 days and works once.

<Screenshot src={shot_users_invite_mail} url="/emails" alt={"The invitation email with the button to activate access"} caption={"The invitation mail is sent in German."} />

<Steps>

1. The link opens the sign-in page with the title <Ui>Activate your access</Ui>, the person's name and email address, and the username, which cannot be changed.

   <Screenshot src={shot_users_accept_invitation} url="/login?invite=<token>" alt={"The page where an invited person chooses a password"} caption={"The rules tick while the person types."} />

2. The person types a password into <Ui>Password</Ui> and again into <Ui>Repeat password</Ui>. Two rules tick as they type: <Ui>At least 12 characters</Ui> and <Ui>Checked against known data breaches when saved</Ui>.

3. They click <Ui>Activate access</Ui>. The page switches to the normal sign-in form with the username filled in, and they sign in with the new password.

</Steps>

nexxus does not sign the person in automatically after they choose the password. The first thing they do is prove that the password they just set works.

The sign-in page and the app are in the default language of your tenant until the person picks their own language on their profile. You set the default under <MenuPath to="Administration > Operations > System configuration" />, section <Ui>Language</Ui>: Deutsch, English or Polski. The invitation mail itself stays German.

## Create an account directly

Some accounts have no mailbox, or you want to hand over the first password in person. For these, nexxus creates the account with a temporary password.

<Steps>

1. On the user list, click <Ui>Create account directly</Ui>.

2. The dialog <Ui>Account created</Ui> shows a generated password. It is made of four groups of five characters, without letters and digits that are easy to confuse (O and 0, I and 1). Click <Ui>Copy</Ui> and pass it on securely. The password is shown **only now**.

   <Screenshot src={shot_users_initial_password} url="/user" alt={"The temporary password shown once after creating an account"} caption={"The temporary password is shown only once."} />

3. Click <Ui>I have noted it down</Ui>. The dialog does not close any other way, so nobody loses the password by clicking next to it. The new user's detail page opens: fill in the name, email and company there.

4. At the first sign-in the person sees <Ui>Password change required</Ui> and must choose their own password before they can continue.

</Steps>

## Resend or withdraw an invitation

An invitation link is valid for 7 days. The app has no button to send it again or to withdraw it. In the app you delete the pending user (see [Remove access](#remove-access)) and invite again.

For automation, both actions exist in the API and need an administrator:

```http
POST   /api/admin/user-invitation/{id}/resend   # new link, the old one stops working
DELETE /api/admin/user-invitation/{id}          # deletes an account whose invitation was never accepted
```

A resent invitation invalidates the previous link. Withdrawing fails with „Diese Einladung wurde bereits angenommen.“ (this invitation has already been accepted) once the person has set their password.

## The user list

The page <Ui>Users</Ui> shows one card per account: picture or initials, name, ID, username and email, the chip <Ui>Invitation pending</Ui> where it applies, one chip per system role, and when the account was created and last changed.

- **Search** in the field above the list. It matches username, first and last name and email.
- **Filter** by <Ui>Role</Ui> (the system roles) and by <Ui>Last edited</Ui>.
- **Sort** by last edited, created or username.
- The panel on the right shows an <Ui>Overview</Ui> (<Ui>Total users</Ui>, <Ui>Active</Ui>, <Ui>Administrators</Ui>, <Ui>Role types</Ui>), the <Ui>Role distribution</Ui> and the <Ui>Recent activity</Ui>. <Ui>Active</Ui> counts every account that is not deleted, including pending invitations.
- **Several accounts at once:** select the cards and click <Ui>Delete</Ui> in the selection bar.

## The user detail page

Click a card to open the person. The ⓘ next to the name opens <Ui>Additional information</Ui>: the username, when the account was created and last changed, and, where it applies, that the invitation is still pending or that the password must be changed at the next sign-in.

<Screenshot src={shot_users_detail} url="/user/:id/data" alt={"A user's detail page with its tabs and the menu More actions"} />

| Tab | Shown when | What you do there |
|---|---|---|
| <Ui>Master data</Ui> | Always | Name, initials, colour, <Ui>Company / branch</Ui>, username, email, the system roles under <Ui>Roles</Ui>, and the switch between <Ui>Person</Ui> and <Ui>Service account</Ui> |
| <Ui>Employee</Ui> | The person's branch belongs to an own company | The employee profile: team, billing role and level, time tracking, and the assigned work schedules |
| <Ui>Time & vacation</Ui> | An employee profile exists | Vacation entitlement, agreements, overtime account, calendar entries |
| <Ui>Access roles</Ui> | The user has been saved | Which access roles the person holds, tenant-wide or per business unit. See [Roles and rights](/setup/roles/#assign-roles-to-people) |
| <Ui>Activity</Ui> | You are an administrator | Sign-ins, failed attempts, password changes and data changes of this account |
| <Ui>Security</Ui> | Always | Whether a password is set and whether two-factor authentication is active, with <Ui>Reset 2FA</Ui> |

The tabs leave out what belongs to a switched-off area: team and working time models without teams & working time models, the billing role without invoices, the time tracking section with Toggl ID and timesheet approval without time tracking, and on the tab <Ui>Time & vacation</Ui> the tables of switched-off areas.

The menu <Ui>More actions</Ui> (⋮) in the bar at the bottom of the page, next to <Ui>Save</Ui>, holds <Ui>Impersonate</Ui>, <Ui>Change password</Ui>, <Ui>Require/lift password change</Ui>, <Ui>Close</Ui> and <Ui>Delete</Ui>.

- <Ui>Change password</Ui> sets a new password for the account: <Ui>Sets a new password for this account. The old sign-in stops working afterwards.</Ui> The server applies the same rules as everywhere (at least 12 characters, no known leaked password). Every remembered browser of the person asks for the second factor again, and remembered sign-ins (<Ui>Stay signed in</Ui>) are removed on all devices.
- <Ui>Require/lift password change</Ui> makes the person choose a new password at their next sign-in, or takes that requirement back.
- <Ui>Reset 2FA</Ui> on the tab <Ui>Security</Ui> removes the person's authenticator app when they have lost their phone. Details in [Security](/setup/security/#two-factor-authentication).

### Act as another user

When someone reports "I can't see the invoice", the quickest way to understand it is to look with their eyes. <Ui>Impersonate</Ui> lets an administrator act as another person for a limited time.

<Steps>

1. On the person's detail page, open <Ui>More actions</Ui> (⋮) next to <Ui>Save</Ui> and click <Ui>Impersonate</Ui>.

2. The dialog <Ui>Impersonate user</Ui> asks for a <Ui>Reason (optional)</Ui>, for example a support ticket number. Click <Ui>Start impersonation</Ui>.

   <Screenshot src={shot_users_impersonation_dialog} url="/user/:id/data" alt={"The dialog for acting as another user, with a reason"} caption={"nexxus records the reason with the impersonation."} />

3. At the foot of the menu, a red box now sits above the profile: <Ui>Signed in as</Ui> with the person's name, and <Ui>Ends in</Ui> with the time left. A thin red frame runs around the whole window. Everything you do now happens under their identity. To end it, click <Ui>Back to</Ui> followed by your own username, for example <Ui>Back to admin</Ui>. With the menu collapsed, the profile picture has a red ring, and the box sits at the top of the window that opens when you click the profile picture.

</Steps>

<Screenshot src={shot_users_impersonation_box} url="/dashboard" alt={"The red box at the foot of the menu while an admin acts as another user"} caption={"Impersonation ends by itself after 60 minutes."} />

The session ends by itself after 60 minutes. While it runs, nexxus refuses to edit or delete users, change passwords or edit the profile. You cannot impersonate yourself, and an administrator cannot impersonate another administrator. nexxus records who impersonated whom, when, from where and with which reason.

## Remove access

nexxus has no switch to deactivate an account. To take access away, you delete the user: on the detail page via <Ui>More actions</Ui> (⋮) and <Ui>Delete</Ui>, or for several people from the list. The confirmation reads <Ui>Do you really want to delete this user?</Ui>

Deleting is a soft delete. The record stays in the database for the history, so changes made by the person still show who made them. nexxus renames the username in the same step, which frees the name for a new account. The person's API tokens stop working at once, because nexxus checks the account on every call.

## How an account links to a person and a company

An account in nexxus is more than a login. Through its branch it belongs to a company, and that company decides what kind of person it is.

<Hub
  inputsLabel="Account"
  inputs={[
    { icon: 'user-round', title: 'User', text: 'Username, email, system roles, access roles' },
  ]}
  core={{
    title: 'Company / branch',
    text: 'Set on the tab Master data',
    items: ['Own company', 'Customer'],
  }}
  outputsLabel="Makes the person"
  outputs={[
    { icon: 'id-card', title: 'An employee', text: 'Branch of an own company: employee profile, time tracking, public holidays of the branch' },
    { icon: 'building-2', title: 'A contact at a customer', text: 'Branch of a customer: no employee profile' },
  ]}
  caption="Administrators and system accounts are the only accounts that need no company."
/>

- **Own company.** If the branch belongs to an own company, the person is an employee. The tab <Ui>Employee</Ui> appears, and their public holidays follow the federal state of the branch. Without an employee profile they can neither record time nor be billed: create one with <Ui>Create employee profile</Ui>.
- **Customer.** If the branch belongs to a customer, the person is a contact at that customer, for example a client who should see their project documents.
- **The company is required** for every account except administrators and system accounts. Saving a person without one fails with a message saying that a person belongs to a company.
- A person cannot change their own company. That would let them make themselves an employee.
- **Contacts are not accounts.** The contacts you keep on a customer record are address data. They have no login and no link to a user.

## Service accounts

Some work runs without a person at the keyboard: an AI schedule that checks the inbox every morning, a mailbox that files incoming mail. That work needs an identity with its own rights. In nexxus this is a **service account**.

On the tab <Ui>Master data</Ui>, switch the account type from <Ui>Person</Ui> to <Ui>Service account</Ui>. The hint says what changes: <Ui>Runs AI schedules; signing in with this account is not possible.</Ui> Nobody can sign in with a service account, and API tokens do not work for it either. Give it access roles like any other account: they decide what the schedules running under it may do.

## Your tenant

All accounts, records and settings of your organisation live in one **tenant** (in German *Mandant*), a separate data space of the installation. Most installations have exactly one.

The tenant gets its name from <Ui>Organization name</Ui> in the setup. To rename it later, open <MenuPath to="Administration > Company > Tenants" />, click the tenant and change <Ui>Name</Ui>. The panel also lists the own companies that belong to the tenant; you create and edit them under <Ui>Own companies</Ui>. Only a superadmin creates new tenants there (<Ui>Create tenant</Ui>). How nexxus keeps tenants apart is described in [Security](/setup/security/#tenant-separation).

## What happens behind the scenes

- **The account exists before the person accepts.** nexxus creates it with a random password nobody knows and marks it as pending. Every invited account also gets the system role STAFF, the basic role for people who work in the app.
- **The link is a one-time token.** nexxus stores only a hash of it. It is valid for 7 days and used up when the password is set. Opening the link without submitting does not use it up, so reloading the page is safe.
- **Roles are written together with the account.** If the invitation names no role, nexxus assigns the default role from the setup, tenant-wide.
- **The company is saved in a second step.** If that fails, the invitation still goes out, and nexxus tells you to add the company in the person's master data.
- **Mail.** The invitation is queued and only leaves when mail sending is switched on and the mail server is confirmed.

:::note[For self-hosters]
The link in the email points to `app.frontend.base-url` (environment variable `APP_FRONTEND_BASEURL`). Set it to the public address of the app, otherwise links in invitations point nowhere. The product name in the subject comes from `app.auth.product-name`. Mail is switched on with `APP_EMAIL_ENABLED=true` and the `SPRING_MAIL_*` settings.
:::

## When something goes wrong

Messages from the server are in German. The meaning is in brackets.

| Message | Cause and fix |
|---|---|
| „Nur Administratoren dürfen Einladungen verwalten.“ (only administrators may manage invitations) | Your account lacks the system role ADMIN. Ask an administrator. |
| „Der Benutzername ... ist bereits vergeben.“ (username already taken) | Usernames are unique across the installation. Choose another one. |
| „Zu dieser E-Mail-Adresse existiert bereits ein Konto.“ (an account with this email exists) | Open the existing account instead. |
| „Bitte eine gültige E-Mail-Adresse angeben.“ (enter a valid email address) | Check the address for typos. |
| <Ui>The invitation could not be sent.</Ui> | Check the mail settings in the setup step <Ui>Email</Ui>. |
| The person reports <Ui>Invitation no longer valid</Ui> | The link is older than 7 days, was already used, or a newer invitation replaced it. Delete the pending user and invite again. |
| „Das Passwort muss mindestens 12 Zeichen lang sein.“ (at least 12 characters) | The password is too short. |
| The person cannot click <Ui>Activate access</Ui> | The password is shorter than 12 characters. Once they leave the field, the field and the rule <Ui>At least 12 characters</Ui> turn red. A longer password enables the button. |
| „Dieses Passwort taucht in bekannten Datenlecks auf und kann nicht verwendet werden.“ (this password appears in known data breaches) | The person chooses another password. |
| An invited person sees an empty menu | They hold no access role that opens a page. Assign one on the tab <Ui>Access roles</Ui>. |

## Next steps

<CardGrid>
  <LinkCard title="Roles and rights" description="Decide who may do what, and what the AI Assistant may do for each person." href="/setup/roles/" />
  <LinkCard title="Sign-in and OAuth" description="Let your people sign in with Microsoft." href="/setup/sign-in/" />
  <LinkCard title="Security" description="Two-factor authentication, sessions, API tokens and the audit log." href="/setup/security/" />
</CardGrid>