Admin Management
Creating a Staff Account
Staff accounts are created via a CLI script inside the running API container. They cannot be created via the web UI — self-registration is blocked for @ctsolutions.gr emails.
sudo docker exec -it <api_container_name> sh -c \
"node dist/scripts/create-admin.js <email> <tempPassword> <firstName> <lastName> <role>"
Example:
sudo docker exec -it pcmr-api sh -c \
Valid roles: admin, superadmin
The account is created with mustChangePassword: true. The new staff member must complete the first-login flow before accessing the portal:
- Log in at
staff.pcmr.gr/staff/login - Change the temporary password
- Verify their email (check inbox for verification email)
- Set up TOTP 2FA (scan QR code with any TOTP app)
- Access the portal
Finding the Container Name
sudo docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
Look for the container running the API image. In Coolify, the container name typically includes the app name and a hash.
Changing a User's Role
Via the staff portal UI:
- Navigate to
/staff/portal/users - Find the user
- Click on the user
- Use the role dropdown to change
Via API (if UI unavailable):
curl -X PATCH https://api.pcmr.gr/admin/users/<userId>/role \
-H "Cookie: __Secure-better-auth.session_token=<your_session>" \
-H "Content-Type: application/json" \
-d '{"role": "superadmin"}'
Restrictions:
- Cannot change your own role
RolesGuardrequires@ctsolutions.gremail foradmin/superadminroles — assigning these roles to non-staff emails is blocked
Banning a Customer
Customer accounts (role: user) can be banned. Staff accounts cannot be banned via the UI — use the database directly if needed.
Via the staff portal UI:
- Navigate to
/staff/portal/users - Find the customer
- Click "Ban user"
- Enter ban reason and optional expiry date
What banning does:
- Sets
User.banned = true,User.banReason,User.banExpires - Revokes all active sessions for the user immediately
- The user will be logged out on their next request
Unbanning:
- Navigate to the user in the staff portal
- Click "Unban user"
- Clears
banned,banReason,banExpires - The user can log in again immediately
What the First-Login Flow Looks Like (for a New Staff Member)
The new staff member receives their temporary password from the person who created their account.
- Go to
staff.pcmr.gr— Cloudflare Access will ask for email OTP verification first - Log in at
/staff/loginwith the temporary password - Step 1 — Change password: Required immediately. The new password must meet minimum requirements.
- Step 2 — Verify email: A verification email is sent to their
@ctsolutions.graddress. They click the link to verify. - Step 3 — TOTP setup: Scan the QR code with any authenticator app (Google Authenticator, Authy, 1Password, etc.). Enter the 6-digit code to confirm setup.
- Portal access is granted.
If a step fails:
- Email not received: Check Zoho SMTP logs; check spam folder; verify the email address is correct
- TOTP not working: Verify device clock is synchronized (TOTP is time-based); try another authenticator app
- Locked out after 10 failed sign-in attempts: The rate limit resets after 15 minutes
Resetting a Staff Member's MFA
If a staff member loses their TOTP device, there is currently no self-service MFA reset. Options:
-
Direct database update (requires prod DB access):
UPDATE "user"SET "twoFactorEnabled" = falseDELETE FROM "twoFactor"Then the user goes through TOTP setup again.
-
Create a new account: If the old account can't be recovered, create a new staff account and delete the old one (archive their data first if needed).
Security Notes
- Never share session tokens or temporary passwords over unencrypted channels
- Temporary passwords should be changed before first use —
mustChangePassword: trueenforces this - The CLI script is the only way to create
superadminaccounts — no API endpoint can elevate tosuperadmin - All role changes are audit-logged in the API logs (Loki)