A shop can see its handsets, and stop one - #892
Conversation
Owner: "once logged in use jwt or proper app authendication system. map device to cloud account." The first half was already true and is unchanged. A handset signs in once with a username and a password and is handed a bearer token, which is the only thing it presents afterwards; the password is never stored on the phone. THE SECOND HALF WAS NOT. A phone described itself on every ORDER it sent - its model, its platform, a random id it keeps for itself - and an order was the only place any of it was ever written down. So a shop had a record of what a phone had DONE and no record of the phone, and no answer to the question that matters when one goes missing: stop THAT phone, leave the other four working. Which is also what makes the thirty day token safe. A long credential is fine when it can be revoked and dangerous when the only control is an expiry, because an expiry does nothing tonight and everything in a month. utils/handsets.js the register: remember, revoked, list, setRevoked routes/handsets.js GET / to see them, POST /:id/revoke and /:id/allow middleware/auth.js the token names the phone, and the door checks it users.controller.js a sign-in writes the phone down before signing The claim is IN THE TOKEN rather than in a header, because a header is whatever the caller types and a phone that names itself can name another. It is set from the request, so every other caller keeps the token it already had, down to its claims: only the handset sign-in puts a device on the request. The check sits in continueWithTenant, after the tenant is attached, because that is the first moment there is a shop to ask and every authenticated route passes through it. A stopped phone gets 403 and DEVICE_REVOKED, not 401: the credential is perfectly good and signing in again with the same one would change nothing. SIGNING IN AGAIN ON A STOPPED PHONE LETS IT BACK, deliberately. The premise of the whole feature is that a waiter does not know the shop's password, so somebody who can type it is somebody the shop trusts with the till. Revoking is for the phone in a taxi, not for keeping a manager out of one. The row keeps that it was stopped. An app that sends no device signs in exactly as it did, and a database that will not answer refuses nobody: a list is not a thing to lock a floor out for. The licence is not on the row. Every shop has its own database, so the row is already inside the only tenancy boundary there is, and mobile-app-reachability holds that handler to never letting the licence out. The first version stored it and that test said so. 21 tests, including that one.
The generated one, which is checked on every push: three endpoints and a group. Prettier on the new file at the same time.
|
CI is currently red, so this is not ready to merge yet. The API job reports that README still claims 661 endpoints while generated API docs report 664; run |
The register and its three endpoints landed first, and for a few hours this
shop had a way to stop a phone that nothing could reach. That is the shape of
the kitchen announcement, which shipped complete and switched off for its whole
life because the only way to turn it on was a developer console. A feature
nothing can reach is a feature nobody has.
Manage > Handsets, beside Employees, because it answers the same kind of
question: who, and on what, is taking orders in this shop.
Phone the model, with the platform and app version beneath
Used by who last signed in on it
Last used in the words a person would use, exact time in the title
Status in use, or stopped
and the button for whichever it is
Stopping one is asked about, because it takes a waiter's phone out of service
mid-shift and whoever is doing it is in a hurry. The question says what happens
next rather than "are you sure", which answers nothing: it stops taking orders
at once, and the shop password lets it back. Letting one back is not asked
about, since nothing is lost by it and the person has already decided.
What a phone said about itself is escaped; what this file says is <lang>
markup, so the walker translates it in place. That is the house pattern and the
only one the coverage tool can see - a string built by concatenation inside a
<lang> element reaches _english.json with the join in it, which is a key no
translator can answer. There is a test for that, because it happened here.
Tamil and Hindi carry all fifteen new words. The other fifteen packs fall to
the translation pipeline; coverage stays inside its ratchet.
The server's five new sentences are in the server text list, regenerated.
npm run badges:fix. Two checks read this number from opposite ends: the README claim, and docs/API.md generated from the routes themselves. Adding a route and not the badge fails both, which is the point of them.
The conflict was in ta.json and hi.json and it was additive on both sides: develop added its keys at the end, this branch added fifteen for the handset screen. Taken as a union and sorted, so the next merge has less to argue with. _english.json and the server text list regenerated afterwards, because both are generated from what the union now holds.
|
Merged to Try it at https://develop.posnic.io, or run it yourself: git fetch origin develop && git checkout develop
npm install && npm --prefix api install
npm run dev # then http://localhost:3000When you have tested it, say what you did and what happened, and set Reporting that something is broken is as useful as fixing it. It is |
Owner: "once logged in use jwt or proper app authendication system. map device to cloud account."
The first half was already true
A handset posts a username and a password once, is handed a bearer token, and presents that from then on. The password is never stored on the phone. Nothing here changes it.
The second half was not
A phone described itself on every order it sent, its model, its platform, a random id it keeps for itself, and an order was the only place any of it was ever written down. So a shop had a record of what a phone had done and no record of the phone, and no answer to the question that matters when one goes missing: stop that phone, leave the other four working.
Which is also what makes the thirty day token safe. A long credential is fine when it can be revoked and dangerous when the only control is an expiry, because an expiry does nothing tonight and everything in a month.
utils/handsets.jsremember,revoked,list,setRevokedroutes/handsets.routes.jsGET /handsets,POST /handsets/:id/revoke,POST /handsets/:id/allowmiddleware/auth.jsusers.controller.jsThe claim is in the token, not a header. A header is whatever the caller types, and a phone that names itself can name another one. It is read off the request rather than passed as an argument, so every other caller keeps the token it already had down to its claims: only the handset sign-in puts a device on the request.
The check sits in
continueWithTenant, after the tenant is attached, because that is the first moment there is a shop to ask and every authenticated route passes through it. Answered for thirty seconds from a small cache, so a floor of phones does not put a query behind every tap; a revoke performed in the same process is felt immediately.403 and
DEVICE_REVOKED, not 401. The credential is perfectly good and signing in again with the same one would change nothing. captain says "the shop has turned this phone off" rather than "free a slot", which are two different nos that send somebody to different screens.Two calls worth disagreeing with
Signing in again on a stopped phone lets it back. The premise of the whole feature is that a waiter does not know the shop's password, so anybody who can type it is somebody trusted with the till. Revoking is for the phone in a taxi, not for keeping a manager out of one. The row keeps that it was stopped.
Nothing here can lock a floor out. An app that sends no device signs in exactly as it did, a phone nobody has heard of is never refused, and a database that will not answer refuses nobody. A handset list is not a thing to stop a shop trading for.
One round lost
The first version stored the licence on the row and
mobile-app-reachabilitycaught it: that handler must never let the licence out. Each shop has its own database, so the row never needed it. There is now a test for that too.21 tests. The phone's half is Posnic/captain#138.