Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/0m1n3m/contacts-db/llms.txt

Use this file to discover all available pages before exploring further.

Contacts DB uses invitation-only registration — there is no public sign-up page. The only way for a new person to join your workspace is for an admin to send them an invitation email. This keeps your team list clean and ensures every user is assigned a deliberate role from their very first login.
Only users with the admin role can send invitations. Editors and viewers do not have access to the /admin/invitations area.

Sending an invitation

Admins manage team invitations from the dedicated admin panel. The process is straightforward:
  1. Navigate to /admin/invitations.
  2. Enter the invitee’s email address.
  3. Choose the role to assign: admin, editor, or viewer.
  4. Submit the form (POST /admin/invitations).
Contacts DB generates a cryptographically random 64-character token, hashes it with SHA-256, and stores the hash in the user_invitations table — the plain token is never persisted. The invitee receives an email containing a unique acceptance link in the form:
https://your-app.com/invitations/accept?token=<plain_token>
The invitation record includes the following fields:
FieldDescription
emailInvitee’s email address (unique per invitation)
roleRole that will be assigned on account creation
token_hashSHA-256 hash of the plain token
expires_atTimestamp 48 hours after the invitation was sent
accepted_atSet to now() when the invitation is used; null if still pending
invited_byForeign key to the admin who sent the invitation
If an invitation already exists for the same email address and has not been accepted yet, submitting the form replaces the previous invitation (via updateOrCreate) and sends a fresh token.

Accepting an invitation

1

Click the link in the email

The invitee opens the email and clicks the acceptance link. The browser makes a GET request to /invitations/accept?token=<plain_token>. The server hashes the incoming token, looks it up in user_invitations, and verifies that the invitation exists, has not already been accepted, and has not expired. If any check fails, a 404 response is returned.
2

Fill in the registration form

Contacts DB renders a form pre-filled with the invitee’s email address (read-only). The invitee enters:
  • Name — their display name
  • Password — minimum 8 characters
  • Password confirmation — must match the password field
No username is required. The email address is already known from the invitation and cannot be changed.
3

Submit the form to create the account

On POST /invitations/accept, the server validates the form data, re-verifies the token, and creates (or updates) the user record with the name, hashed password, pre-assigned role, and a verified email timestamp. The accepted_at field on the invitation is set to the current time so the link cannot be reused.
4

Automatic login and redirect

After account creation the user is automatically logged in via Auth::login($user) and redirected to the contacts list at /contacts. No separate login step is required.

Invitation expiry

Invitations are valid for 48 hours from the time they are sent. After that window the acceptance link becomes invalid and the invitee will receive a 404 response if they try to use it. An admin can re-invite the same email address — this replaces the expired record and sends a new 48-hour link. The expiry logic is handled by the isExpired() method on the UserInvitation model:
public function isExpired(): bool
{
    return now()->greaterThan($this->expires_at);
}

Managing invitations

Admins can review all invitations — both pending and accepted — at /admin/invitations. The list is sorted by most recently created and paginated at 30 records per page. This gives you a full audit trail of who was invited, by whom, and whether they have completed registration.

Email configuration

Invitations require a working outbound mail driver. The UserInvitationMail mailable sends the invitation using whatever MAIL_MAILER is configured in your .env file.
Configure a real SMTP provider such as Mailgun, Postmark, or SendGrid:
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your_username
MAIL_PASSWORD=your_password
MAIL_FROM_ADDRESS=noreply@yourapp.com
MAIL_FROM_NAME="Contacts DB"

Build docs developers (and LLMs) love