docs
/
Appmint Mobile

Staff and access

Who can sign in, how quick sign-in and NFC access cards are controlled, and what happens when a device is blocked or an account is removed.

Appmint Mobile is a staff app. Every sign-in produces a user token for one organization, and everything the app does is attributed to that person. This page is the administrator's view: what to configure so a counter tablet, a rep's phone and a manager's iPad each get the right kind of access.

Two kinds of identity

IdentityWhoHow it signs inWhat it can reach
User (staff)Employees, managers, adminsPassword, magic code, passcode or NFC cardThe whole app, scoped by the roles on the account
CustomerGuests and attendeesNot through this appCustomer-facing products such as EventOxygen

Every request the app makes carries the user token plus a lowercase orgid header. Signing in to a second organization does not merge anything — it is a separate token, held as a separate saved session on the device.

What each person sees

Which screens appear — home-grid apps, bottom tabs and More-menu sections — is set per role in the console under Role & Permission › Menu access › Mobile app. Each screen is a path /mobile/<group>/<item> (for example /mobile/businessmade/pos), listed in the SDK's MOBILE_APP_MENU.

The app reads this off the sign-in response, not a separate request: data.permissions.menu carries one entry per role. For each role the app grants every screen at or below the role's default tier (everyone → maker → manager → admin), adds the mobile paths the role includes, and drops the ones it excludes; the person sees the union across roles. A role with the all tier (Owner, System, the Root roles) sees everything. If the profile carries no menu entries at all, nothing is hidden. See Menu access.

Hiding a screen is not a permission; the server still checks every request.

Sign-in methods available

MethodEndpointNotes
Email and passwordPOST /profile/user/signinThe default.
Magic codeGET /profile/user/magic-link?type=code then POST /profile/user/magic-link/redirectA 6-digit code emailed to the address; entered in the app.
Quick sign-inPOST /profile/user/signin/passcodeEmployee id plus passcode, or an NFC card tap. Meant for shared devices.
Saved sessionPOST /profile/user/refreshOne tap on a remembered account; uses the stored refresh token.

There is no Google, Apple or Facebook sign-in and no biometric unlock. The magic code is the only code-based path the app offers, and it replaces the password rather than adding to it.

Two-factor verification

The apps answer the challenge now. When one is due, sign-in returns requiresTwoFactor with a challengeToken and no tokens, and emails or texts the code; Appmint Mobile and Stowbo recognise that response, ask for the code, and can resend it or switch between email and SMS. Authenticator codes work too. event_app and dfw_errand have always handled it.

This used to lock people out

Older builds read a challenge as a successful sign-in with an empty token and looped on Session expired. Please sign in again. If anyone is still on such a build, update the app — turning the setting off is no longer the fix.

Three settings raise a challenge:

SettingEffect
securitySettings.enableTwoFactorForUsersEvery staff sign-in is challenged
securitySettings.enableTwoFactorForCustomersSame for customers — this is the one that reaches Stowbo
securitySettings.enableNewDeviceAuthenticationAnyone signing in on an unrecognised device is challenged, with or without 2FA — a replacement phone is enough to trigger it

Two paths skip the challenge entirely, which is worth knowing before you rely on it as a control:

  • Quick sign-in — employee id and passcode, or an access card. Deliberately exempt so a busy terminal is not interrupted.
  • Magic code — the magic-link path performs no 2FA check at all.
That second path is also a gap in the control

If your organization requires 2FA, be aware the magic-code route ignores it. Anyone who can read the account's mailbox can sign in without the second factor. Treat "2FA required" as not yet enforced across every sign-in path.

"Forgot password" does not reset anything yet

The link on the sign-in screen shows a confirmation but calls no endpoint. Reset passwords from Studio Manager, or have the person sign in with a magic code.

Quick sign-in settings

Quick sign-in is switched on and shaped by one org-level setting, read by the app from the base setting record (GET /repository/find-by-attribute/setting/name/base-setting, field passcodeLoginSettings):

FieldValuesEffect
enabletrue / falseWhether the quick sign-in screen accepts anything at all
modepasscodeA registered card and the person's PIN are required
instantA registered card alone signs the person in; typing an employee id still needs the PIN

The server is the source of truth. The app does not decide the mode; it asks, and if a PIN-less card tap comes back rejected it simply reveals the PIN field and lets the person continue.

Passcodes

Each employee sets their own 6-digit passcode from More → My quick-login passcode, which links it to their BusinessMade employee id. Administrators do not see passcodes; they can only remove one so the person sets a new one.

POST/profile/passcode/setUSER
POST/profile/passcode/removeUSER
GET/business-made/employees?keyword=USER

The employee id comes from BusinessMade staff records. An account with no employee id cannot use quick sign-in, whatever the org setting says.

NFC access cards

Cards are issued from More → Access cards (admin). The screen is admin-only: the server answers 403 to anyone else, and the app surfaces that as the error rather than hiding the screen.

1. Pick the employee. Search by name or id.

2. Tap the blank card. The app prompts Tap the new card to read it… and listens for about 25 seconds — on the phone's own NFC, or on a paired Bluetooth reader. It reads the chip's factory serial (cardUid) and, where the device has built-in NFC, writes the employee id into the card's NDEF text record.

3. Register it. Confirm the UID and employee, add an optional Label — Lanyard #3 — and the server stores the pairing of serial and employee.

A card read through a Bluetooth reader is registered server-side only; nothing is written to the chip, and it works the same at sign-in because the serial is what matters.

POST/profile/passcode/card/registerUSER
POST/profile/passcode/card/statusUSER
GET/profile/passcode/cardsUSER
GET/profile/passcode/cards/:employeeIdUSER
GET/profile/passcode/card/:identifierUSER

Two things on the card matter, and they have different jobs:

On the cardWritable?Purpose
Chip UIDNo — burned at the factoryThe anti-clone key. A copied NDEF record on a different chip does not match.
Employee id (NDEF text)Yes — written at issueTells the app whose card it is without a lookup

A card's status is active, revoked or lost, set from the ⋮ on its row (Set active, Revoke, Mark lost). Set it to lost the moment someone reports one missing; issue a replacement afterwards. Revoking does not touch the employee's passcode, so they can still type in.

There is no confirmation on Revoke or Mark lost — the first tap takes effect. Set active on the same row undoes it. Replacing a card is two steps: mark the old one lost, then issue a new one to the same employee.

Devices without NFC still read cards

An iPad has no NFC reader. Pair a Bluetooth NFC reader under More → Devices → NFC card reader and card taps arrive through it instead. See pairing hardware.

Saved sessions and shared devices

The sign-in screen remembers accounts that have signed in on that device, as tiles. Tapping one refreshes its token silently; if the refresh token has expired the tile falls back to the password step. Signing out keeps the remembered organization and the saved sessions on purpose — a shared till should not need the org id retyped every shift. It keeps nothing else: the printer, card reader, scanner, NFC reader, selected location and home layout are all cleared, which is why staff on a shared device should use quick sign-in rather than signing in and out.

That is the intended pattern for a shared device: quick sign-in for staff on the floor, and one saved manager session for the person who closes.

Blocked devices and forced sign-out

The server can reject a device fingerprint outright, and it can invalidate a session. The app treats either as a forced sign-out: it clears its stored tokens, returns to the sign-in screen and shows a warning for a few seconds explaining why. Nothing in the app can undo a block; that is done from the administration side. See two-factor and devices.

Tokens live in the device's secure storage (Keychain or Keystore), not in plain preferences. A token refresh is attempted once on a 401; a second failure signs the person out rather than leaving the app half-working.

Removing an account

The endpoint exists (DELETE /profile/user/self) and the server refuses to delete the organization's primary contact, so the owner account cannot be removed by accident. The screen that calls it has no entry point in the current build, so in practice account deletion is done from Studio Manager — worth knowing when a staff member asks, and worth tracking as an app-store requirement. Anything else about staff lifecycle — roles, deactivation, password resets — is done in Studio Manager, not in the app.

When something goes wrong

SymptomCauseFix
A staff member sees Forbidden — insufficient permissions on Access cardsThey are not an administratorExpected. Issue the card yourself; the screen opens for everyone but the data does not load.
That employee has no employee ID when issuingTheir BusinessMade staff record is incompleteAdd an employee id to the record; quick sign-in needs it regardless of the org setting.
No card read after tappingThe 25-second window closed, or the chip did not readHold the card flat against the back of the phone and retry. Metal surfaces and phone cases interfere.
No NFC reader…The device has neither built-in NFC nor a paired readerIssue from an NFC phone, or pair a Bluetooth reader under More → Devices.
A card is rejected at the tillIts status is revoked or lost, or it is registered to another orgCheck the card list; Set active if it was killed by mistake.
A card tap asks for a PINThe org is in passcode modeExpected. The person types their six digits as well.
Someone cannot set a passcodeThey are typing the wrong employee id, or have noneThe screen does not prefill it — give them the id from their staff record.
Sign-in loops with Session expired for everyone at onceAn old build with no challenge handling, plus org-wide two-factorUpdate the app — the current build asks for the code. See above.
One person is stuck after getting a new phoneNew-device verification, on an old buildSame fix. A new device raises a challenge without 2FA being on at all.
Everyone on one device sees the same hidden tilesThe home layout is device storage, not per personExpected. Note it is cleared when anyone signs out.