Authentication¶
AbraFlexi offers two basic REST API authentication methods, plus an advanced one for server-side solutions.
HTTP authentication¶
The simplest method — send a standard Authorization: Basic header with
every request:
curl -u winstrom:winstrom \
'https://demo.flexibee.eu:5434/c/demo/adresar.json?detail=custom:kod&limit=1'
If the header is missing, the server redirects to a login form, or returns
401 Authorization required. Credentials can also be sent directly in the
URL: https://user:password@server:5434/c/company/evidence. The
?auth=http parameter forces HTTP auth even where SSO would otherwise be
offered; ?auth=html forces the login form.
JSON authentication (login session)¶
Useful when making multiple requests and you don’t want to resend the password each time. Obtaining a token:
POST /login-logout/login.json
Request body (raw JSON, not form data):
{
"username": "novak",
"password": "password",
"otp": "123456"
}
otp is optional (one-time password, if two-factor login is required).
This method only returns results as JSON.
Successful response:
{
"success": true,
"authSessionId": "00112233445566778899aabbccddeeff..."
}
Failed response:
{
"success": false,
"errors": {"reason": "Wrong username or password was entered."}
}
The obtained token can be passed on subsequent requests in three ways:
Cookie:
authSessionId=00112233...HTTP header:
X-authSessionId: 00112233...URL parameter:
?authSessionId=00112233...(careful: in this case credentials get logged on the server)
To keep the token alive, periodically call
GET /login-logout/session-keep-alive.js (recommended every ~60s, though
once every 30 minutes should suffice). If you have a refreshToken, a new
authSessionId can be obtained via GET /login-logout/check with that
token sent as a cookie.
Logging out a specific user:
POST /status/user/{username}/logout
A custom login form can be embedded on another site via a plain HTML form
posting to /login-logout/login.html (supports a returnUrl parameter,
and otp for two-factor login; not usable with SSO — OpenID or SAMLv2).
Note
Practical note: some HTTP clients (curl, Postman) require the
application/x-www-form-urlencoded or multipart/form-data header
for /login-logout/login.json, otherwise the request body may not be
recognized correctly.
Two-factor authentication (2FA)¶
2FA can be managed via the REST API as well as in the UI. Source: podpora.flexibee.eu.
Warning
Enabled 2FA also applies to REST calls with HTTP authentication. Every
request from that user must include the query parameter otp with the
current one-time password — otherwise integrations stop working. Prefer
not enabling 2FA on pure service accounts.
Status (also present in GET /u listings):
GET /u/{username}.xml — look for <twoPhaseAuthEnabled>true|false</…>
Issue a QR code (PNG 400×400) and read the private key from the Secret
response header:
GET /u/{username}/qrcode-2fa.png
# or Accept: image/png — without .png / Accept → 404
# already-active 2FA → 403
Enable / disable:
PUT /u/{username}/enable-2fa?secret={secret}&otp={otp-code}
PUT /u/{username}/disable-2fa?otp={otp-code}
An administrator with the Change User Passwords permission can disable another user’s 2FA without their OTP:
PUT /u/disable-2fa?username={username}
Access rights and roles¶
The web interface (and REST API the same way) automatically enforces access rights defined on the user’s role:
A user might have no access to an evidence at all, or read-only access.
They might see/edit only some records (e.g. only their own department).
They might see/edit only some columns (e.g. without purchase prices).
The application license might not permit a feature at all.
If an import modifies fields the user has no rights to, those changes are silently ignored; if it would modify a whole record without rights, the whole operation is rejected with an error.
Roles themselves are accessible via the role evidence:
GET /c/{company}/role — list of roles
GET /c/{company}/role/{ID} — a role including all its permissions
PUT/POST /c/{company}/role — create/update a role
A new (user-defined, standard=false) role must have kod, nazev
and otecRole (base/parent role it inherits permissions from, unless
explicitly overridden in the request). Standard (standard=true) roles
are immutable; their permission ids have the form uuid:{roleCode}-{permissionKey}.
Example: set a specific permission on an existing role (issued invoices read-only, received invoices fully inaccessible):
{
"winstrom": {
"role": {
"id": "code:ADMIN_COPY",
"pristPrava": {
"pristupove-pravo": [
{"groupKey": "dDoklFak$$FAV", "typeK": "typPristPrav.pouzeCist"},
{"groupKey": "dDoklFak$$FAP", "typeK": "typPristPrav.nepripustne"}
]
}
}
}
}
typeK values: typPristPrav.plny (full access), nepripustne
(no access), pouzeCist (read-only), upresneni (refined, via
featureK sub-features — Pridavat/Menit/Mazat/Export/Import/
OteviratDetail/Sloupce/Kusovnik/Storno/SlevaZmenaCeny/Sumace/Sluzby/Vazby/
HromZmeny/NakupCena/…).
Users as an evidence¶
Users are a normal evidence (uzivatel); creating a new user additionally
requires matching password/passwordAgain:
XML |
JSON |
|---|---|
<uzivatel>
<id>code:einstein</id>
<kod>einstein</kod>
<jmeno>Albert</jmeno>
<prijmeni>Einstein</prijmeni>
<password>password</password>
<passwordAgain>password</passwordAgain>
<role>code:JENCIST</role>
</uzivatel>
|
{
"winstrom": {
"uzivatel": [
{
"id": "code:einstein",
"kod": "einstein",
"jmeno": "Albert",
"prijmeni": "Einstein",
"password": "password",
"passwordAgain": "password",
"role": "code:JENCIST"
}
]
}
}
|
Last login is tracked in lastLoginDate (regular users) /
lastApiDate (API users), visible via GET /u.json?detail=full
(the /u/ prefix = server-level, outside any specific company).