User Invitations
Accountability provides a secure invitation system for adding users to organizations. Invitations include role assignments, functional roles, and secure token-based acceptance.Invitation Flow
The complete invitation workflow:Admin creates invitation
Organization admin or owner creates an invitation for a user’s email address, specifying role and functional roles.
System generates secure token
A cryptographically secure token (256 bits) is generated. The token hash is stored in the database.
Token sent to invitee
The raw token is sent to the invitee via email (token is only available once).
Invitee accepts or declines
User clicks link to accept (creating membership) or decline (revoking invitation).
Invitations do not expire automatically. They remain pending until accepted, declined, or revoked by an admin.
Invitation Roles
Invitations can assign three roles (owner cannot be assigned via invitation):| Role | Access Level | Use Case |
|---|---|---|
| admin | Full data operations and member management | Department heads, senior accountants |
| member | Access based on functional roles | Accounting staff, finance team |
| viewer | Read-only access | Auditors, executives |
Functional Roles
Invitations can also assign functional roles:| Functional Role | Key Permissions |
|---|---|
| controller | Period lock/unlock, consolidation oversight |
| finance_manager | Account management, exchange rates |
| accountant | Journal entry operations |
| period_admin | Period open/close operations |
| consolidation_manager | Consolidation group management |
Creating Invitations
API Endpoint
Using InvitationService
In backend code:packages/core/src/membership/InvitationService.ts
Business Rules
Invitation Validation
Invitation Validation
Email validation:
- Must be a valid email format
- Can invite the same email multiple times (previous invitation must be accepted/declined first)
- Role must be
admin,member, orviewer - Cannot invite as
owner(use transfer ownership instead)
- Can specify zero or more functional roles
- Functional roles are applied when invitation is accepted
- Only admins and owners can create invitations
- Checked via
organization:invite_memberpermission
Token Security
Token Security
Token generation:
- 256-bit cryptographically secure random token
- Base64url encoded for URL safety
- Generated using
crypto.getRandomValues()or equivalent
- Only SHA-256 hash stored in database
- Raw token never stored or logged
- Token only returned once (on invitation creation)
- Hash must match stored hash
- Invitation must be in “pending” status
- No expiration check (invitations don’t expire)
Accepting Invitations
API Endpoint
Using InvitationService
What Happens on Acceptance
If a user already exists in the system (same email), the invitation is linked to their existing account. If not, they may need to register first.
Declining Invitations
API Endpoint
Using InvitationService
Declining an invitation marks it as “revoked”. The same user can be invited again later if needed.
Revoking Invitations (Admin)
Admins and owners can revoke pending invitations:API Endpoint
Using InvitationService
- User no longer needs access
- Invitation sent to wrong email
- Role/functional roles need to change (revoke and re-invite)
- User left company before accepting
Listing Invitations
User’s Pending Invitations
Users can see invitations sent to their email:Organization’s Pending Invitations
Admins and owners can see all pending invitations for an organization:Domain Models
OrganizationInvitation
The invitation entity:packages/core/src/membership/OrganizationInvitation.ts
InvitationStatus
Invitation lifecycle states:| Status | Description |
|---|---|
| pending | Invitation created, awaiting response |
| accepted | User accepted and membership created |
| revoked | Invitation declined by user or revoked by admin |
packages/core/src/membership/InvitationStatus.ts
Member Management
Once a user accepts an invitation, they become a member of the organization.Organization Membership
packages/core/src/membership/OrganizationMembership.ts
Updating Member Roles
Admins and owners can update member roles:Removing Members
Admins and owners can remove members (soft delete):Reinstating Members
Previously removed members can be reinstated:Frontend Integration
Members Page
The members management page provides a complete UI for:- Viewing active members
- Viewing inactive members (suspended/removed)
- Inviting new members
- Editing member roles
- Removing members
- Reinstating removed members
- Viewing pending invitations
- Revoking invitations
packages/web/src/routes/organizations/$organizationId/settings/members.tsx
Invitation Components
InviteMemberModal:User Invitation Acceptance
When a user clicks an invitation link:Email Integration
The invitation system requires email integration for sending invitation links:Email Template
Subject: You’ve been invited to join [Organization Name] Body:Email service integration is not included in the core system. Implement using your preferred email service (SendGrid, Mailgun, etc.).
Troubleshooting
Invitation Issues
Invitation Issues
“Invalid invitation” error:
- Check token is correct (no extra spaces/characters)
- Verify invitation hasn’t been accepted or revoked
- Confirm invitation exists in database
- Check user has admin or owner role
- Verify organization exists
- Check no pending invitation exists for this email
- Check email service logs
- Verify email address is correct
- Check spam folder
- Confirm email service credentials are valid
Acceptance Issues
Acceptance Issues
“User already member” error:
- User already has membership in this organization
- Check if they should update role instead
- Revoke invitation if not needed
- Invitations don’t expire, but can be revoked
- Check invitation status in database
- Admin may need to create new invitation
- Declining marks invitation as revoked
- Admin must create new invitation
Member Management Issues
Member Management Issues
Cannot remove owner:
- Owners cannot be removed directly
- Must transfer ownership first
- Then previous owner can be removed if needed
- Check user has admin or owner permission
- Verify membership exists and is active
- Confirm new role is valid
- Can only reinstate removed members
- Check membership status is “removed”
- Verify user has admin/owner permission